├── .cargo └── config.toml ├── .github └── workflows │ └── MainDistributionPipeline.yml ├── .gitignore ├── .gitmodules ├── Cargo.lock ├── Cargo.toml ├── Makefile ├── README.md ├── src ├── lib.rs └── wasm_lib.rs └── test ├── sql └── pcap_reader.test └── test.pcap /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # statically linking the C runtime on windows seems sensible? 2 | [target.x86_64-pc-windows-msvc] 3 | rustflags = ["-Ctarget-feature=+crt-static"] -------------------------------------------------------------------------------- /.github/workflows/MainDistributionPipeline.yml: -------------------------------------------------------------------------------- 1 | # 2 | # This workflow calls the main distribution pipeline from DuckDB to build, test and (optionally) release the extension 3 | # 4 | name: Main Extension Distribution Pipeline 5 | on: 6 | push: 7 | paths-ignore: 8 | - '**/*.md' 9 | pull_request: 10 | workflow_dispatch: 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref || '' }}-${{ github.base_ref || '' }}-${{ github.ref != 'refs/heads/main' || github.sha }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | duckdb-stable-build: 18 | name: Build extension binaries 19 | uses: duckdb/extension-ci-tools/.github/workflows/_extension_distribution.yml@v1.2.0 20 | with: 21 | duckdb_version: v1.2.2 22 | ci_tools_version: main 23 | extension_name: pcap_reader 24 | extra_toolchains: rust;python3 25 | exclude_archs: 'wasm_mvp;wasm_eh;wasm_threads;windows_amd64_rtools;windows_amd64_mingw;linux_amd64_musl' 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | build 3 | configure 4 | .idea 5 | duckdb_unittest_tempdir 6 | /test/bin 7 | venv -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "extension-ci-tools"] 2 | branch = v1.2.0 3 | path = extension-ci-tools 4 | url = https://github.com/duckdb/extension-ci-tools 5 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "adler2" 7 | version = "2.0.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 10 | 11 | [[package]] 12 | name = "ahash" 13 | version = "0.7.8" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" 16 | dependencies = [ 17 | "getrandom", 18 | "once_cell", 19 | "version_check", 20 | ] 21 | 22 | [[package]] 23 | name = "ahash" 24 | version = "0.8.11" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 27 | dependencies = [ 28 | "cfg-if", 29 | "const-random", 30 | "getrandom", 31 | "once_cell", 32 | "version_check", 33 | "zerocopy", 34 | ] 35 | 36 | [[package]] 37 | name = "aho-corasick" 38 | version = "1.1.3" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 41 | dependencies = [ 42 | "memchr", 43 | ] 44 | 45 | [[package]] 46 | name = "android-tzdata" 47 | version = "0.1.1" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 50 | 51 | [[package]] 52 | name = "android_system_properties" 53 | version = "0.1.5" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 56 | dependencies = [ 57 | "libc", 58 | ] 59 | 60 | [[package]] 61 | name = "arrayvec" 62 | version = "0.7.6" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 65 | 66 | [[package]] 67 | name = "arrow" 68 | version = "54.2.0" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "755b6da235ac356a869393c23668c663720b8749dd6f15e52b6c214b4b964cc7" 71 | dependencies = [ 72 | "arrow-arith", 73 | "arrow-array", 74 | "arrow-buffer", 75 | "arrow-cast", 76 | "arrow-data", 77 | "arrow-ord", 78 | "arrow-row", 79 | "arrow-schema", 80 | "arrow-select", 81 | "arrow-string", 82 | ] 83 | 84 | [[package]] 85 | name = "arrow-arith" 86 | version = "54.2.0" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "64656a1e0b13ca766f8440752e9a93e11014eec7b67909986f83ed0ab1fe37b8" 89 | dependencies = [ 90 | "arrow-array", 91 | "arrow-buffer", 92 | "arrow-data", 93 | "arrow-schema", 94 | "chrono", 95 | "num", 96 | ] 97 | 98 | [[package]] 99 | name = "arrow-array" 100 | version = "54.2.0" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "57a4a6d2896083cfbdf84a71a863b22460d0708f8206a8373c52e326cc72ea1a" 103 | dependencies = [ 104 | "ahash 0.8.11", 105 | "arrow-buffer", 106 | "arrow-data", 107 | "arrow-schema", 108 | "chrono", 109 | "half", 110 | "hashbrown 0.15.2", 111 | "num", 112 | ] 113 | 114 | [[package]] 115 | name = "arrow-buffer" 116 | version = "54.2.0" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "cef870583ce5e4f3b123c181706f2002fb134960f9a911900f64ba4830c7a43a" 119 | dependencies = [ 120 | "bytes", 121 | "half", 122 | "num", 123 | ] 124 | 125 | [[package]] 126 | name = "arrow-cast" 127 | version = "54.2.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "1ac7eba5a987f8b4a7d9629206ba48e19a1991762795bbe5d08497b7736017ee" 130 | dependencies = [ 131 | "arrow-array", 132 | "arrow-buffer", 133 | "arrow-data", 134 | "arrow-schema", 135 | "arrow-select", 136 | "atoi", 137 | "base64", 138 | "chrono", 139 | "comfy-table", 140 | "half", 141 | "lexical-core", 142 | "num", 143 | "ryu", 144 | ] 145 | 146 | [[package]] 147 | name = "arrow-data" 148 | version = "54.2.0" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "b095e8a4f3c309544935d53e04c3bfe4eea4e71c3de6fe0416d1f08bb4441a83" 151 | dependencies = [ 152 | "arrow-buffer", 153 | "arrow-schema", 154 | "half", 155 | "num", 156 | ] 157 | 158 | [[package]] 159 | name = "arrow-ord" 160 | version = "54.2.0" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "6c07223476f8219d1ace8cd8d85fa18c4ebd8d945013f25ef5c72e85085ca4ee" 163 | dependencies = [ 164 | "arrow-array", 165 | "arrow-buffer", 166 | "arrow-data", 167 | "arrow-schema", 168 | "arrow-select", 169 | ] 170 | 171 | [[package]] 172 | name = "arrow-row" 173 | version = "54.2.0" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "91b194b38bfd89feabc23e798238989c6648b2506ad639be42ec8eb1658d82c4" 176 | dependencies = [ 177 | "arrow-array", 178 | "arrow-buffer", 179 | "arrow-data", 180 | "arrow-schema", 181 | "half", 182 | ] 183 | 184 | [[package]] 185 | name = "arrow-schema" 186 | version = "54.2.0" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "0f40f6be8f78af1ab610db7d9b236e21d587b7168e368a36275d2e5670096735" 189 | dependencies = [ 190 | "bitflags", 191 | ] 192 | 193 | [[package]] 194 | name = "arrow-select" 195 | version = "54.2.0" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "ac265273864a820c4a179fc67182ccc41ea9151b97024e1be956f0f2369c2539" 198 | dependencies = [ 199 | "ahash 0.8.11", 200 | "arrow-array", 201 | "arrow-buffer", 202 | "arrow-data", 203 | "arrow-schema", 204 | "num", 205 | ] 206 | 207 | [[package]] 208 | name = "arrow-string" 209 | version = "54.2.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "d44c8eed43be4ead49128370f7131f054839d3d6003e52aebf64322470b8fbd0" 212 | dependencies = [ 213 | "arrow-array", 214 | "arrow-buffer", 215 | "arrow-data", 216 | "arrow-schema", 217 | "arrow-select", 218 | "memchr", 219 | "num", 220 | "regex", 221 | "regex-syntax", 222 | ] 223 | 224 | [[package]] 225 | name = "atoi" 226 | version = "2.0.0" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" 229 | dependencies = [ 230 | "num-traits", 231 | ] 232 | 233 | [[package]] 234 | name = "autocfg" 235 | version = "1.4.0" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 238 | 239 | [[package]] 240 | name = "base64" 241 | version = "0.22.1" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 244 | 245 | [[package]] 246 | name = "bitflags" 247 | version = "2.6.0" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 250 | 251 | [[package]] 252 | name = "bitvec" 253 | version = "1.0.1" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" 256 | dependencies = [ 257 | "funty", 258 | "radium", 259 | "tap", 260 | "wyz", 261 | ] 262 | 263 | [[package]] 264 | name = "borsh" 265 | version = "1.5.3" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" 268 | dependencies = [ 269 | "borsh-derive", 270 | "cfg_aliases", 271 | ] 272 | 273 | [[package]] 274 | name = "borsh-derive" 275 | version = "1.5.3" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" 278 | dependencies = [ 279 | "once_cell", 280 | "proc-macro-crate", 281 | "proc-macro2", 282 | "quote", 283 | "syn 2.0.95", 284 | ] 285 | 286 | [[package]] 287 | name = "bumpalo" 288 | version = "3.16.0" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 291 | 292 | [[package]] 293 | name = "bytecheck" 294 | version = "0.6.12" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" 297 | dependencies = [ 298 | "bytecheck_derive", 299 | "ptr_meta", 300 | "simdutf8", 301 | ] 302 | 303 | [[package]] 304 | name = "bytecheck_derive" 305 | version = "0.6.12" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" 308 | dependencies = [ 309 | "proc-macro2", 310 | "quote", 311 | "syn 1.0.109", 312 | ] 313 | 314 | [[package]] 315 | name = "byteorder" 316 | version = "1.5.0" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 319 | 320 | [[package]] 321 | name = "bytes" 322 | version = "1.9.0" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" 325 | 326 | [[package]] 327 | name = "cast" 328 | version = "0.3.0" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" 331 | 332 | [[package]] 333 | name = "cc" 334 | version = "1.2.7" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" 337 | dependencies = [ 338 | "shlex", 339 | ] 340 | 341 | [[package]] 342 | name = "cfg-if" 343 | version = "1.0.0" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 346 | 347 | [[package]] 348 | name = "cfg_aliases" 349 | version = "0.2.1" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 352 | 353 | [[package]] 354 | name = "chrono" 355 | version = "0.4.39" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" 358 | dependencies = [ 359 | "android-tzdata", 360 | "iana-time-zone", 361 | "num-traits", 362 | "windows-targets", 363 | ] 364 | 365 | [[package]] 366 | name = "circular" 367 | version = "0.3.0" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "b0fc239e0f6cb375d2402d48afb92f76f5404fd1df208a41930ec81eda078bea" 370 | 371 | [[package]] 372 | name = "comfy-table" 373 | version = "7.1.3" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "24f165e7b643266ea80cb858aed492ad9280e3e05ce24d4a99d7d7b889b6a4d9" 376 | dependencies = [ 377 | "strum 0.26.3", 378 | "strum_macros 0.26.4", 379 | "unicode-width", 380 | ] 381 | 382 | [[package]] 383 | name = "const-random" 384 | version = "0.1.18" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" 387 | dependencies = [ 388 | "const-random-macro", 389 | ] 390 | 391 | [[package]] 392 | name = "const-random-macro" 393 | version = "0.1.16" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" 396 | dependencies = [ 397 | "getrandom", 398 | "once_cell", 399 | "tiny-keccak", 400 | ] 401 | 402 | [[package]] 403 | name = "core-foundation-sys" 404 | version = "0.8.7" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 407 | 408 | [[package]] 409 | name = "crc32fast" 410 | version = "1.4.2" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 413 | dependencies = [ 414 | "cfg-if", 415 | ] 416 | 417 | [[package]] 418 | name = "crunchy" 419 | version = "0.2.2" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 422 | 423 | [[package]] 424 | name = "darling" 425 | version = "0.20.10" 426 | source = "registry+https://github.com/rust-lang/crates.io-index" 427 | checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" 428 | dependencies = [ 429 | "darling_core", 430 | "darling_macro", 431 | ] 432 | 433 | [[package]] 434 | name = "darling_core" 435 | version = "0.20.10" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" 438 | dependencies = [ 439 | "fnv", 440 | "ident_case", 441 | "proc-macro2", 442 | "quote", 443 | "strsim", 444 | "syn 2.0.95", 445 | ] 446 | 447 | [[package]] 448 | name = "darling_macro" 449 | version = "0.20.10" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" 452 | dependencies = [ 453 | "darling_core", 454 | "quote", 455 | "syn 2.0.95", 456 | ] 457 | 458 | [[package]] 459 | name = "displaydoc" 460 | version = "0.2.5" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 463 | dependencies = [ 464 | "proc-macro2", 465 | "quote", 466 | "syn 2.0.95", 467 | ] 468 | 469 | [[package]] 470 | name = "document-features" 471 | version = "0.2.10" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" 474 | dependencies = [ 475 | "litrs", 476 | ] 477 | 478 | [[package]] 479 | name = "duckdb" 480 | version = "1.2.0" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "8e2093a18d0c07e411104a9d27ef0097872172552ad5774feba304c2b47f382c" 483 | dependencies = [ 484 | "arrow", 485 | "cast", 486 | "duckdb-loadable-macros", 487 | "fallible-iterator", 488 | "fallible-streaming-iterator", 489 | "hashlink", 490 | "libduckdb-sys", 491 | "memchr", 492 | "num-integer", 493 | "rust_decimal", 494 | "smallvec", 495 | "strum 0.25.0", 496 | ] 497 | 498 | [[package]] 499 | name = "duckdb-loadable-macros" 500 | version = "0.1.4" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "a0514910d370bd12b9a5a7bf6631e4709f4217e39a6b7ef0e7bff9bf4521239b" 503 | dependencies = [ 504 | "darling", 505 | "proc-macro2", 506 | "quote", 507 | "syn 2.0.95", 508 | ] 509 | 510 | [[package]] 511 | name = "ehttp" 512 | version = "0.5.0" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "59a81c221a1e4dad06cb9c9deb19aea1193a5eea084e8cd42d869068132bf876" 515 | dependencies = [ 516 | "document-features", 517 | "js-sys", 518 | "ureq", 519 | "wasm-bindgen", 520 | "wasm-bindgen-futures", 521 | "web-sys", 522 | ] 523 | 524 | [[package]] 525 | name = "equivalent" 526 | version = "1.0.1" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 529 | 530 | [[package]] 531 | name = "errno" 532 | version = "0.3.10" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 535 | dependencies = [ 536 | "libc", 537 | "windows-sys 0.59.0", 538 | ] 539 | 540 | [[package]] 541 | name = "fallible-iterator" 542 | version = "0.3.0" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" 545 | 546 | [[package]] 547 | name = "fallible-streaming-iterator" 548 | version = "0.1.9" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" 551 | 552 | [[package]] 553 | name = "filetime" 554 | version = "0.2.25" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" 557 | dependencies = [ 558 | "cfg-if", 559 | "libc", 560 | "libredox", 561 | "windows-sys 0.59.0", 562 | ] 563 | 564 | [[package]] 565 | name = "flate2" 566 | version = "1.0.35" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" 569 | dependencies = [ 570 | "crc32fast", 571 | "miniz_oxide", 572 | ] 573 | 574 | [[package]] 575 | name = "fnv" 576 | version = "1.0.7" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 579 | 580 | [[package]] 581 | name = "form_urlencoded" 582 | version = "1.2.1" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 585 | dependencies = [ 586 | "percent-encoding", 587 | ] 588 | 589 | [[package]] 590 | name = "funty" 591 | version = "2.0.0" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" 594 | 595 | [[package]] 596 | name = "getrandom" 597 | version = "0.2.15" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 600 | dependencies = [ 601 | "cfg-if", 602 | "libc", 603 | "wasi", 604 | ] 605 | 606 | [[package]] 607 | name = "half" 608 | version = "2.4.1" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" 611 | dependencies = [ 612 | "cfg-if", 613 | "crunchy", 614 | "num-traits", 615 | ] 616 | 617 | [[package]] 618 | name = "hashbrown" 619 | version = "0.12.3" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 622 | dependencies = [ 623 | "ahash 0.7.8", 624 | ] 625 | 626 | [[package]] 627 | name = "hashbrown" 628 | version = "0.14.5" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 631 | dependencies = [ 632 | "ahash 0.8.11", 633 | ] 634 | 635 | [[package]] 636 | name = "hashbrown" 637 | version = "0.15.2" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 640 | 641 | [[package]] 642 | name = "hashlink" 643 | version = "0.9.1" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" 646 | dependencies = [ 647 | "hashbrown 0.14.5", 648 | ] 649 | 650 | [[package]] 651 | name = "heck" 652 | version = "0.4.1" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 655 | 656 | [[package]] 657 | name = "heck" 658 | version = "0.5.0" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 661 | 662 | [[package]] 663 | name = "hex" 664 | version = "0.4.3" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 667 | 668 | [[package]] 669 | name = "iana-time-zone" 670 | version = "0.1.61" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" 673 | dependencies = [ 674 | "android_system_properties", 675 | "core-foundation-sys", 676 | "iana-time-zone-haiku", 677 | "js-sys", 678 | "wasm-bindgen", 679 | "windows-core", 680 | ] 681 | 682 | [[package]] 683 | name = "iana-time-zone-haiku" 684 | version = "0.1.2" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 687 | dependencies = [ 688 | "cc", 689 | ] 690 | 691 | [[package]] 692 | name = "icu_collections" 693 | version = "1.5.0" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 696 | dependencies = [ 697 | "displaydoc", 698 | "yoke", 699 | "zerofrom", 700 | "zerovec", 701 | ] 702 | 703 | [[package]] 704 | name = "icu_locid" 705 | version = "1.5.0" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 708 | dependencies = [ 709 | "displaydoc", 710 | "litemap", 711 | "tinystr", 712 | "writeable", 713 | "zerovec", 714 | ] 715 | 716 | [[package]] 717 | name = "icu_locid_transform" 718 | version = "1.5.0" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 721 | dependencies = [ 722 | "displaydoc", 723 | "icu_locid", 724 | "icu_locid_transform_data", 725 | "icu_provider", 726 | "tinystr", 727 | "zerovec", 728 | ] 729 | 730 | [[package]] 731 | name = "icu_locid_transform_data" 732 | version = "1.5.0" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 735 | 736 | [[package]] 737 | name = "icu_normalizer" 738 | version = "1.5.0" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 741 | dependencies = [ 742 | "displaydoc", 743 | "icu_collections", 744 | "icu_normalizer_data", 745 | "icu_properties", 746 | "icu_provider", 747 | "smallvec", 748 | "utf16_iter", 749 | "utf8_iter", 750 | "write16", 751 | "zerovec", 752 | ] 753 | 754 | [[package]] 755 | name = "icu_normalizer_data" 756 | version = "1.5.0" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 759 | 760 | [[package]] 761 | name = "icu_properties" 762 | version = "1.5.1" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 765 | dependencies = [ 766 | "displaydoc", 767 | "icu_collections", 768 | "icu_locid_transform", 769 | "icu_properties_data", 770 | "icu_provider", 771 | "tinystr", 772 | "zerovec", 773 | ] 774 | 775 | [[package]] 776 | name = "icu_properties_data" 777 | version = "1.5.0" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 780 | 781 | [[package]] 782 | name = "icu_provider" 783 | version = "1.5.0" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 786 | dependencies = [ 787 | "displaydoc", 788 | "icu_locid", 789 | "icu_provider_macros", 790 | "stable_deref_trait", 791 | "tinystr", 792 | "writeable", 793 | "yoke", 794 | "zerofrom", 795 | "zerovec", 796 | ] 797 | 798 | [[package]] 799 | name = "icu_provider_macros" 800 | version = "1.5.0" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 803 | dependencies = [ 804 | "proc-macro2", 805 | "quote", 806 | "syn 2.0.95", 807 | ] 808 | 809 | [[package]] 810 | name = "ident_case" 811 | version = "1.0.1" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 814 | 815 | [[package]] 816 | name = "idna" 817 | version = "1.0.3" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 820 | dependencies = [ 821 | "idna_adapter", 822 | "smallvec", 823 | "utf8_iter", 824 | ] 825 | 826 | [[package]] 827 | name = "idna_adapter" 828 | version = "1.2.0" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 831 | dependencies = [ 832 | "icu_normalizer", 833 | "icu_properties", 834 | ] 835 | 836 | [[package]] 837 | name = "indexmap" 838 | version = "2.7.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" 841 | dependencies = [ 842 | "equivalent", 843 | "hashbrown 0.15.2", 844 | ] 845 | 846 | [[package]] 847 | name = "itoa" 848 | version = "1.0.14" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" 851 | 852 | [[package]] 853 | name = "js-sys" 854 | version = "0.3.76" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" 857 | dependencies = [ 858 | "once_cell", 859 | "wasm-bindgen", 860 | ] 861 | 862 | [[package]] 863 | name = "lexical-core" 864 | version = "1.0.5" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "b765c31809609075565a70b4b71402281283aeda7ecaf4818ac14a7b2ade8958" 867 | dependencies = [ 868 | "lexical-parse-float", 869 | "lexical-parse-integer", 870 | "lexical-util", 871 | "lexical-write-float", 872 | "lexical-write-integer", 873 | ] 874 | 875 | [[package]] 876 | name = "lexical-parse-float" 877 | version = "1.0.5" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | checksum = "de6f9cb01fb0b08060209a057c048fcbab8717b4c1ecd2eac66ebfe39a65b0f2" 880 | dependencies = [ 881 | "lexical-parse-integer", 882 | "lexical-util", 883 | "static_assertions", 884 | ] 885 | 886 | [[package]] 887 | name = "lexical-parse-integer" 888 | version = "1.0.5" 889 | source = "registry+https://github.com/rust-lang/crates.io-index" 890 | checksum = "72207aae22fc0a121ba7b6d479e42cbfea549af1479c3f3a4f12c70dd66df12e" 891 | dependencies = [ 892 | "lexical-util", 893 | "static_assertions", 894 | ] 895 | 896 | [[package]] 897 | name = "lexical-util" 898 | version = "1.0.6" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "5a82e24bf537fd24c177ffbbdc6ebcc8d54732c35b50a3f28cc3f4e4c949a0b3" 901 | dependencies = [ 902 | "static_assertions", 903 | ] 904 | 905 | [[package]] 906 | name = "lexical-write-float" 907 | version = "1.0.5" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "c5afc668a27f460fb45a81a757b6bf2f43c2d7e30cb5a2dcd3abf294c78d62bd" 910 | dependencies = [ 911 | "lexical-util", 912 | "lexical-write-integer", 913 | "static_assertions", 914 | ] 915 | 916 | [[package]] 917 | name = "lexical-write-integer" 918 | version = "1.0.5" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "629ddff1a914a836fb245616a7888b62903aae58fa771e1d83943035efa0f978" 921 | dependencies = [ 922 | "lexical-util", 923 | "static_assertions", 924 | ] 925 | 926 | [[package]] 927 | name = "libc" 928 | version = "0.2.169" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" 931 | 932 | [[package]] 933 | name = "libduckdb-sys" 934 | version = "1.2.0" 935 | source = "registry+https://github.com/rust-lang/crates.io-index" 936 | checksum = "dc4020eaf07df4927b5205cd200ca2a5ed0798b49652dec22e09384ba8efa163" 937 | dependencies = [ 938 | "autocfg", 939 | "flate2", 940 | "pkg-config", 941 | "prettyplease", 942 | "quote", 943 | "serde", 944 | "serde_json", 945 | "syn 2.0.95", 946 | "tar", 947 | "vcpkg", 948 | ] 949 | 950 | [[package]] 951 | name = "libm" 952 | version = "0.2.11" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" 955 | 956 | [[package]] 957 | name = "libredox" 958 | version = "0.1.3" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 961 | dependencies = [ 962 | "bitflags", 963 | "libc", 964 | "redox_syscall", 965 | ] 966 | 967 | [[package]] 968 | name = "linux-raw-sys" 969 | version = "0.4.15" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 972 | 973 | [[package]] 974 | name = "litemap" 975 | version = "0.7.4" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" 978 | 979 | [[package]] 980 | name = "litrs" 981 | version = "0.4.1" 982 | source = "registry+https://github.com/rust-lang/crates.io-index" 983 | checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" 984 | 985 | [[package]] 986 | name = "log" 987 | version = "0.4.22" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 990 | 991 | [[package]] 992 | name = "memchr" 993 | version = "2.7.4" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 996 | 997 | [[package]] 998 | name = "minimal-lexical" 999 | version = "0.2.1" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 1002 | 1003 | [[package]] 1004 | name = "miniz_oxide" 1005 | version = "0.8.2" 1006 | source = "registry+https://github.com/rust-lang/crates.io-index" 1007 | checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" 1008 | dependencies = [ 1009 | "adler2", 1010 | ] 1011 | 1012 | [[package]] 1013 | name = "nom" 1014 | version = "7.1.3" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 1017 | dependencies = [ 1018 | "memchr", 1019 | "minimal-lexical", 1020 | ] 1021 | 1022 | [[package]] 1023 | name = "num" 1024 | version = "0.4.3" 1025 | source = "registry+https://github.com/rust-lang/crates.io-index" 1026 | checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" 1027 | dependencies = [ 1028 | "num-bigint", 1029 | "num-complex", 1030 | "num-integer", 1031 | "num-iter", 1032 | "num-rational", 1033 | "num-traits", 1034 | ] 1035 | 1036 | [[package]] 1037 | name = "num-bigint" 1038 | version = "0.4.6" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" 1041 | dependencies = [ 1042 | "num-integer", 1043 | "num-traits", 1044 | ] 1045 | 1046 | [[package]] 1047 | name = "num-complex" 1048 | version = "0.4.6" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" 1051 | dependencies = [ 1052 | "num-traits", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "num-integer" 1057 | version = "0.1.46" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 1060 | dependencies = [ 1061 | "num-traits", 1062 | ] 1063 | 1064 | [[package]] 1065 | name = "num-iter" 1066 | version = "0.1.45" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" 1069 | dependencies = [ 1070 | "autocfg", 1071 | "num-integer", 1072 | "num-traits", 1073 | ] 1074 | 1075 | [[package]] 1076 | name = "num-rational" 1077 | version = "0.4.2" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" 1080 | dependencies = [ 1081 | "num-bigint", 1082 | "num-integer", 1083 | "num-traits", 1084 | ] 1085 | 1086 | [[package]] 1087 | name = "num-traits" 1088 | version = "0.2.19" 1089 | source = "registry+https://github.com/rust-lang/crates.io-index" 1090 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1091 | dependencies = [ 1092 | "autocfg", 1093 | "libm", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "once_cell" 1098 | version = "1.20.2" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 1101 | 1102 | [[package]] 1103 | name = "pcap-parser" 1104 | version = "0.16.0" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "2f8d57cc6bdf76d7abd6d3cc1113278047dab29c2ff6d97190e8d1c29d4efdac" 1107 | dependencies = [ 1108 | "circular", 1109 | "nom", 1110 | "rusticata-macros", 1111 | ] 1112 | 1113 | [[package]] 1114 | name = "pcap_reader" 1115 | version = "0.1.1" 1116 | dependencies = [ 1117 | "duckdb", 1118 | "duckdb-loadable-macros", 1119 | "ehttp", 1120 | "hex", 1121 | "libduckdb-sys", 1122 | "pcap-parser", 1123 | ] 1124 | 1125 | [[package]] 1126 | name = "percent-encoding" 1127 | version = "2.3.1" 1128 | source = "registry+https://github.com/rust-lang/crates.io-index" 1129 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1130 | 1131 | [[package]] 1132 | name = "pkg-config" 1133 | version = "0.3.31" 1134 | source = "registry+https://github.com/rust-lang/crates.io-index" 1135 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 1136 | 1137 | [[package]] 1138 | name = "ppv-lite86" 1139 | version = "0.2.20" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1142 | dependencies = [ 1143 | "zerocopy", 1144 | ] 1145 | 1146 | [[package]] 1147 | name = "prettyplease" 1148 | version = "0.2.27" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" 1151 | dependencies = [ 1152 | "proc-macro2", 1153 | "syn 2.0.95", 1154 | ] 1155 | 1156 | [[package]] 1157 | name = "proc-macro-crate" 1158 | version = "3.2.0" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" 1161 | dependencies = [ 1162 | "toml_edit", 1163 | ] 1164 | 1165 | [[package]] 1166 | name = "proc-macro2" 1167 | version = "1.0.92" 1168 | source = "registry+https://github.com/rust-lang/crates.io-index" 1169 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 1170 | dependencies = [ 1171 | "unicode-ident", 1172 | ] 1173 | 1174 | [[package]] 1175 | name = "ptr_meta" 1176 | version = "0.1.4" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" 1179 | dependencies = [ 1180 | "ptr_meta_derive", 1181 | ] 1182 | 1183 | [[package]] 1184 | name = "ptr_meta_derive" 1185 | version = "0.1.4" 1186 | source = "registry+https://github.com/rust-lang/crates.io-index" 1187 | checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" 1188 | dependencies = [ 1189 | "proc-macro2", 1190 | "quote", 1191 | "syn 1.0.109", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "quote" 1196 | version = "1.0.38" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" 1199 | dependencies = [ 1200 | "proc-macro2", 1201 | ] 1202 | 1203 | [[package]] 1204 | name = "radium" 1205 | version = "0.7.0" 1206 | source = "registry+https://github.com/rust-lang/crates.io-index" 1207 | checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" 1208 | 1209 | [[package]] 1210 | name = "rand" 1211 | version = "0.8.5" 1212 | source = "registry+https://github.com/rust-lang/crates.io-index" 1213 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1214 | dependencies = [ 1215 | "libc", 1216 | "rand_chacha", 1217 | "rand_core", 1218 | ] 1219 | 1220 | [[package]] 1221 | name = "rand_chacha" 1222 | version = "0.3.1" 1223 | source = "registry+https://github.com/rust-lang/crates.io-index" 1224 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1225 | dependencies = [ 1226 | "ppv-lite86", 1227 | "rand_core", 1228 | ] 1229 | 1230 | [[package]] 1231 | name = "rand_core" 1232 | version = "0.6.4" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1235 | dependencies = [ 1236 | "getrandom", 1237 | ] 1238 | 1239 | [[package]] 1240 | name = "redox_syscall" 1241 | version = "0.5.8" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" 1244 | dependencies = [ 1245 | "bitflags", 1246 | ] 1247 | 1248 | [[package]] 1249 | name = "regex" 1250 | version = "1.11.1" 1251 | source = "registry+https://github.com/rust-lang/crates.io-index" 1252 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1253 | dependencies = [ 1254 | "aho-corasick", 1255 | "memchr", 1256 | "regex-automata", 1257 | "regex-syntax", 1258 | ] 1259 | 1260 | [[package]] 1261 | name = "regex-automata" 1262 | version = "0.4.9" 1263 | source = "registry+https://github.com/rust-lang/crates.io-index" 1264 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1265 | dependencies = [ 1266 | "aho-corasick", 1267 | "memchr", 1268 | "regex-syntax", 1269 | ] 1270 | 1271 | [[package]] 1272 | name = "regex-syntax" 1273 | version = "0.8.5" 1274 | source = "registry+https://github.com/rust-lang/crates.io-index" 1275 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1276 | 1277 | [[package]] 1278 | name = "rend" 1279 | version = "0.4.2" 1280 | source = "registry+https://github.com/rust-lang/crates.io-index" 1281 | checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" 1282 | dependencies = [ 1283 | "bytecheck", 1284 | ] 1285 | 1286 | [[package]] 1287 | name = "ring" 1288 | version = "0.17.8" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 1291 | dependencies = [ 1292 | "cc", 1293 | "cfg-if", 1294 | "getrandom", 1295 | "libc", 1296 | "spin", 1297 | "untrusted", 1298 | "windows-sys 0.52.0", 1299 | ] 1300 | 1301 | [[package]] 1302 | name = "rkyv" 1303 | version = "0.7.45" 1304 | source = "registry+https://github.com/rust-lang/crates.io-index" 1305 | checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" 1306 | dependencies = [ 1307 | "bitvec", 1308 | "bytecheck", 1309 | "bytes", 1310 | "hashbrown 0.12.3", 1311 | "ptr_meta", 1312 | "rend", 1313 | "rkyv_derive", 1314 | "seahash", 1315 | "tinyvec", 1316 | "uuid", 1317 | ] 1318 | 1319 | [[package]] 1320 | name = "rkyv_derive" 1321 | version = "0.7.45" 1322 | source = "registry+https://github.com/rust-lang/crates.io-index" 1323 | checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" 1324 | dependencies = [ 1325 | "proc-macro2", 1326 | "quote", 1327 | "syn 1.0.109", 1328 | ] 1329 | 1330 | [[package]] 1331 | name = "rust_decimal" 1332 | version = "1.36.0" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" 1335 | dependencies = [ 1336 | "arrayvec", 1337 | "borsh", 1338 | "bytes", 1339 | "num-traits", 1340 | "rand", 1341 | "rkyv", 1342 | "serde", 1343 | "serde_json", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "rusticata-macros" 1348 | version = "4.1.0" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" 1351 | dependencies = [ 1352 | "nom", 1353 | ] 1354 | 1355 | [[package]] 1356 | name = "rustix" 1357 | version = "0.38.43" 1358 | source = "registry+https://github.com/rust-lang/crates.io-index" 1359 | checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" 1360 | dependencies = [ 1361 | "bitflags", 1362 | "errno", 1363 | "libc", 1364 | "linux-raw-sys", 1365 | "windows-sys 0.59.0", 1366 | ] 1367 | 1368 | [[package]] 1369 | name = "rustls" 1370 | version = "0.23.20" 1371 | source = "registry+https://github.com/rust-lang/crates.io-index" 1372 | checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" 1373 | dependencies = [ 1374 | "log", 1375 | "once_cell", 1376 | "ring", 1377 | "rustls-pki-types", 1378 | "rustls-webpki", 1379 | "subtle", 1380 | "zeroize", 1381 | ] 1382 | 1383 | [[package]] 1384 | name = "rustls-pki-types" 1385 | version = "1.10.1" 1386 | source = "registry+https://github.com/rust-lang/crates.io-index" 1387 | checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" 1388 | 1389 | [[package]] 1390 | name = "rustls-webpki" 1391 | version = "0.102.8" 1392 | source = "registry+https://github.com/rust-lang/crates.io-index" 1393 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 1394 | dependencies = [ 1395 | "ring", 1396 | "rustls-pki-types", 1397 | "untrusted", 1398 | ] 1399 | 1400 | [[package]] 1401 | name = "rustversion" 1402 | version = "1.0.19" 1403 | source = "registry+https://github.com/rust-lang/crates.io-index" 1404 | checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" 1405 | 1406 | [[package]] 1407 | name = "ryu" 1408 | version = "1.0.18" 1409 | source = "registry+https://github.com/rust-lang/crates.io-index" 1410 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1411 | 1412 | [[package]] 1413 | name = "seahash" 1414 | version = "4.1.0" 1415 | source = "registry+https://github.com/rust-lang/crates.io-index" 1416 | checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" 1417 | 1418 | [[package]] 1419 | name = "serde" 1420 | version = "1.0.217" 1421 | source = "registry+https://github.com/rust-lang/crates.io-index" 1422 | checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" 1423 | dependencies = [ 1424 | "serde_derive", 1425 | ] 1426 | 1427 | [[package]] 1428 | name = "serde_derive" 1429 | version = "1.0.217" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" 1432 | dependencies = [ 1433 | "proc-macro2", 1434 | "quote", 1435 | "syn 2.0.95", 1436 | ] 1437 | 1438 | [[package]] 1439 | name = "serde_json" 1440 | version = "1.0.135" 1441 | source = "registry+https://github.com/rust-lang/crates.io-index" 1442 | checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" 1443 | dependencies = [ 1444 | "itoa", 1445 | "memchr", 1446 | "ryu", 1447 | "serde", 1448 | ] 1449 | 1450 | [[package]] 1451 | name = "shlex" 1452 | version = "1.3.0" 1453 | source = "registry+https://github.com/rust-lang/crates.io-index" 1454 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1455 | 1456 | [[package]] 1457 | name = "simdutf8" 1458 | version = "0.1.5" 1459 | source = "registry+https://github.com/rust-lang/crates.io-index" 1460 | checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" 1461 | 1462 | [[package]] 1463 | name = "smallvec" 1464 | version = "1.13.2" 1465 | source = "registry+https://github.com/rust-lang/crates.io-index" 1466 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1467 | 1468 | [[package]] 1469 | name = "spin" 1470 | version = "0.9.8" 1471 | source = "registry+https://github.com/rust-lang/crates.io-index" 1472 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1473 | 1474 | [[package]] 1475 | name = "stable_deref_trait" 1476 | version = "1.2.0" 1477 | source = "registry+https://github.com/rust-lang/crates.io-index" 1478 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1479 | 1480 | [[package]] 1481 | name = "static_assertions" 1482 | version = "1.1.0" 1483 | source = "registry+https://github.com/rust-lang/crates.io-index" 1484 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1485 | 1486 | [[package]] 1487 | name = "strsim" 1488 | version = "0.11.1" 1489 | source = "registry+https://github.com/rust-lang/crates.io-index" 1490 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1491 | 1492 | [[package]] 1493 | name = "strum" 1494 | version = "0.25.0" 1495 | source = "registry+https://github.com/rust-lang/crates.io-index" 1496 | checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" 1497 | dependencies = [ 1498 | "strum_macros 0.25.3", 1499 | ] 1500 | 1501 | [[package]] 1502 | name = "strum" 1503 | version = "0.26.3" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" 1506 | 1507 | [[package]] 1508 | name = "strum_macros" 1509 | version = "0.25.3" 1510 | source = "registry+https://github.com/rust-lang/crates.io-index" 1511 | checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" 1512 | dependencies = [ 1513 | "heck 0.4.1", 1514 | "proc-macro2", 1515 | "quote", 1516 | "rustversion", 1517 | "syn 2.0.95", 1518 | ] 1519 | 1520 | [[package]] 1521 | name = "strum_macros" 1522 | version = "0.26.4" 1523 | source = "registry+https://github.com/rust-lang/crates.io-index" 1524 | checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" 1525 | dependencies = [ 1526 | "heck 0.5.0", 1527 | "proc-macro2", 1528 | "quote", 1529 | "rustversion", 1530 | "syn 2.0.95", 1531 | ] 1532 | 1533 | [[package]] 1534 | name = "subtle" 1535 | version = "2.6.1" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1538 | 1539 | [[package]] 1540 | name = "syn" 1541 | version = "1.0.109" 1542 | source = "registry+https://github.com/rust-lang/crates.io-index" 1543 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1544 | dependencies = [ 1545 | "proc-macro2", 1546 | "quote", 1547 | "unicode-ident", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "syn" 1552 | version = "2.0.95" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" 1555 | dependencies = [ 1556 | "proc-macro2", 1557 | "quote", 1558 | "unicode-ident", 1559 | ] 1560 | 1561 | [[package]] 1562 | name = "synstructure" 1563 | version = "0.13.1" 1564 | source = "registry+https://github.com/rust-lang/crates.io-index" 1565 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 1566 | dependencies = [ 1567 | "proc-macro2", 1568 | "quote", 1569 | "syn 2.0.95", 1570 | ] 1571 | 1572 | [[package]] 1573 | name = "tap" 1574 | version = "1.0.1" 1575 | source = "registry+https://github.com/rust-lang/crates.io-index" 1576 | checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" 1577 | 1578 | [[package]] 1579 | name = "tar" 1580 | version = "0.4.43" 1581 | source = "registry+https://github.com/rust-lang/crates.io-index" 1582 | checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" 1583 | dependencies = [ 1584 | "filetime", 1585 | "libc", 1586 | "xattr", 1587 | ] 1588 | 1589 | [[package]] 1590 | name = "tiny-keccak" 1591 | version = "2.0.2" 1592 | source = "registry+https://github.com/rust-lang/crates.io-index" 1593 | checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" 1594 | dependencies = [ 1595 | "crunchy", 1596 | ] 1597 | 1598 | [[package]] 1599 | name = "tinystr" 1600 | version = "0.7.6" 1601 | source = "registry+https://github.com/rust-lang/crates.io-index" 1602 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 1603 | dependencies = [ 1604 | "displaydoc", 1605 | "zerovec", 1606 | ] 1607 | 1608 | [[package]] 1609 | name = "tinyvec" 1610 | version = "1.8.1" 1611 | source = "registry+https://github.com/rust-lang/crates.io-index" 1612 | checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" 1613 | dependencies = [ 1614 | "tinyvec_macros", 1615 | ] 1616 | 1617 | [[package]] 1618 | name = "tinyvec_macros" 1619 | version = "0.1.1" 1620 | source = "registry+https://github.com/rust-lang/crates.io-index" 1621 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1622 | 1623 | [[package]] 1624 | name = "toml_datetime" 1625 | version = "0.6.8" 1626 | source = "registry+https://github.com/rust-lang/crates.io-index" 1627 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 1628 | 1629 | [[package]] 1630 | name = "toml_edit" 1631 | version = "0.22.22" 1632 | source = "registry+https://github.com/rust-lang/crates.io-index" 1633 | checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" 1634 | dependencies = [ 1635 | "indexmap", 1636 | "toml_datetime", 1637 | "winnow", 1638 | ] 1639 | 1640 | [[package]] 1641 | name = "unicode-ident" 1642 | version = "1.0.14" 1643 | source = "registry+https://github.com/rust-lang/crates.io-index" 1644 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 1645 | 1646 | [[package]] 1647 | name = "unicode-width" 1648 | version = "0.2.0" 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" 1650 | checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" 1651 | 1652 | [[package]] 1653 | name = "untrusted" 1654 | version = "0.9.0" 1655 | source = "registry+https://github.com/rust-lang/crates.io-index" 1656 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1657 | 1658 | [[package]] 1659 | name = "ureq" 1660 | version = "2.12.1" 1661 | source = "registry+https://github.com/rust-lang/crates.io-index" 1662 | checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" 1663 | dependencies = [ 1664 | "base64", 1665 | "flate2", 1666 | "log", 1667 | "once_cell", 1668 | "rustls", 1669 | "rustls-pki-types", 1670 | "url", 1671 | "webpki-roots", 1672 | ] 1673 | 1674 | [[package]] 1675 | name = "url" 1676 | version = "2.5.4" 1677 | source = "registry+https://github.com/rust-lang/crates.io-index" 1678 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 1679 | dependencies = [ 1680 | "form_urlencoded", 1681 | "idna", 1682 | "percent-encoding", 1683 | ] 1684 | 1685 | [[package]] 1686 | name = "utf16_iter" 1687 | version = "1.0.5" 1688 | source = "registry+https://github.com/rust-lang/crates.io-index" 1689 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 1690 | 1691 | [[package]] 1692 | name = "utf8_iter" 1693 | version = "1.0.4" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1696 | 1697 | [[package]] 1698 | name = "uuid" 1699 | version = "1.11.0" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" 1702 | 1703 | [[package]] 1704 | name = "vcpkg" 1705 | version = "0.2.15" 1706 | source = "registry+https://github.com/rust-lang/crates.io-index" 1707 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1708 | 1709 | [[package]] 1710 | name = "version_check" 1711 | version = "0.9.5" 1712 | source = "registry+https://github.com/rust-lang/crates.io-index" 1713 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1714 | 1715 | [[package]] 1716 | name = "wasi" 1717 | version = "0.11.0+wasi-snapshot-preview1" 1718 | source = "registry+https://github.com/rust-lang/crates.io-index" 1719 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1720 | 1721 | [[package]] 1722 | name = "wasm-bindgen" 1723 | version = "0.2.99" 1724 | source = "registry+https://github.com/rust-lang/crates.io-index" 1725 | checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" 1726 | dependencies = [ 1727 | "cfg-if", 1728 | "once_cell", 1729 | "wasm-bindgen-macro", 1730 | ] 1731 | 1732 | [[package]] 1733 | name = "wasm-bindgen-backend" 1734 | version = "0.2.99" 1735 | source = "registry+https://github.com/rust-lang/crates.io-index" 1736 | checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" 1737 | dependencies = [ 1738 | "bumpalo", 1739 | "log", 1740 | "proc-macro2", 1741 | "quote", 1742 | "syn 2.0.95", 1743 | "wasm-bindgen-shared", 1744 | ] 1745 | 1746 | [[package]] 1747 | name = "wasm-bindgen-futures" 1748 | version = "0.4.49" 1749 | source = "registry+https://github.com/rust-lang/crates.io-index" 1750 | checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" 1751 | dependencies = [ 1752 | "cfg-if", 1753 | "js-sys", 1754 | "once_cell", 1755 | "wasm-bindgen", 1756 | "web-sys", 1757 | ] 1758 | 1759 | [[package]] 1760 | name = "wasm-bindgen-macro" 1761 | version = "0.2.99" 1762 | source = "registry+https://github.com/rust-lang/crates.io-index" 1763 | checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" 1764 | dependencies = [ 1765 | "quote", 1766 | "wasm-bindgen-macro-support", 1767 | ] 1768 | 1769 | [[package]] 1770 | name = "wasm-bindgen-macro-support" 1771 | version = "0.2.99" 1772 | source = "registry+https://github.com/rust-lang/crates.io-index" 1773 | checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" 1774 | dependencies = [ 1775 | "proc-macro2", 1776 | "quote", 1777 | "syn 2.0.95", 1778 | "wasm-bindgen-backend", 1779 | "wasm-bindgen-shared", 1780 | ] 1781 | 1782 | [[package]] 1783 | name = "wasm-bindgen-shared" 1784 | version = "0.2.99" 1785 | source = "registry+https://github.com/rust-lang/crates.io-index" 1786 | checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" 1787 | 1788 | [[package]] 1789 | name = "web-sys" 1790 | version = "0.3.76" 1791 | source = "registry+https://github.com/rust-lang/crates.io-index" 1792 | checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" 1793 | dependencies = [ 1794 | "js-sys", 1795 | "wasm-bindgen", 1796 | ] 1797 | 1798 | [[package]] 1799 | name = "webpki-roots" 1800 | version = "0.26.7" 1801 | source = "registry+https://github.com/rust-lang/crates.io-index" 1802 | checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" 1803 | dependencies = [ 1804 | "rustls-pki-types", 1805 | ] 1806 | 1807 | [[package]] 1808 | name = "windows-core" 1809 | version = "0.52.0" 1810 | source = "registry+https://github.com/rust-lang/crates.io-index" 1811 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 1812 | dependencies = [ 1813 | "windows-targets", 1814 | ] 1815 | 1816 | [[package]] 1817 | name = "windows-sys" 1818 | version = "0.52.0" 1819 | source = "registry+https://github.com/rust-lang/crates.io-index" 1820 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1821 | dependencies = [ 1822 | "windows-targets", 1823 | ] 1824 | 1825 | [[package]] 1826 | name = "windows-sys" 1827 | version = "0.59.0" 1828 | source = "registry+https://github.com/rust-lang/crates.io-index" 1829 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1830 | dependencies = [ 1831 | "windows-targets", 1832 | ] 1833 | 1834 | [[package]] 1835 | name = "windows-targets" 1836 | version = "0.52.6" 1837 | source = "registry+https://github.com/rust-lang/crates.io-index" 1838 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1839 | dependencies = [ 1840 | "windows_aarch64_gnullvm", 1841 | "windows_aarch64_msvc", 1842 | "windows_i686_gnu", 1843 | "windows_i686_gnullvm", 1844 | "windows_i686_msvc", 1845 | "windows_x86_64_gnu", 1846 | "windows_x86_64_gnullvm", 1847 | "windows_x86_64_msvc", 1848 | ] 1849 | 1850 | [[package]] 1851 | name = "windows_aarch64_gnullvm" 1852 | version = "0.52.6" 1853 | source = "registry+https://github.com/rust-lang/crates.io-index" 1854 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1855 | 1856 | [[package]] 1857 | name = "windows_aarch64_msvc" 1858 | version = "0.52.6" 1859 | source = "registry+https://github.com/rust-lang/crates.io-index" 1860 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1861 | 1862 | [[package]] 1863 | name = "windows_i686_gnu" 1864 | version = "0.52.6" 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" 1866 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1867 | 1868 | [[package]] 1869 | name = "windows_i686_gnullvm" 1870 | version = "0.52.6" 1871 | source = "registry+https://github.com/rust-lang/crates.io-index" 1872 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1873 | 1874 | [[package]] 1875 | name = "windows_i686_msvc" 1876 | version = "0.52.6" 1877 | source = "registry+https://github.com/rust-lang/crates.io-index" 1878 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1879 | 1880 | [[package]] 1881 | name = "windows_x86_64_gnu" 1882 | version = "0.52.6" 1883 | source = "registry+https://github.com/rust-lang/crates.io-index" 1884 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1885 | 1886 | [[package]] 1887 | name = "windows_x86_64_gnullvm" 1888 | version = "0.52.6" 1889 | source = "registry+https://github.com/rust-lang/crates.io-index" 1890 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1891 | 1892 | [[package]] 1893 | name = "windows_x86_64_msvc" 1894 | version = "0.52.6" 1895 | source = "registry+https://github.com/rust-lang/crates.io-index" 1896 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1897 | 1898 | [[package]] 1899 | name = "winnow" 1900 | version = "0.6.22" 1901 | source = "registry+https://github.com/rust-lang/crates.io-index" 1902 | checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" 1903 | dependencies = [ 1904 | "memchr", 1905 | ] 1906 | 1907 | [[package]] 1908 | name = "write16" 1909 | version = "1.0.0" 1910 | source = "registry+https://github.com/rust-lang/crates.io-index" 1911 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 1912 | 1913 | [[package]] 1914 | name = "writeable" 1915 | version = "0.5.5" 1916 | source = "registry+https://github.com/rust-lang/crates.io-index" 1917 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 1918 | 1919 | [[package]] 1920 | name = "wyz" 1921 | version = "0.5.1" 1922 | source = "registry+https://github.com/rust-lang/crates.io-index" 1923 | checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" 1924 | dependencies = [ 1925 | "tap", 1926 | ] 1927 | 1928 | [[package]] 1929 | name = "xattr" 1930 | version = "1.4.0" 1931 | source = "registry+https://github.com/rust-lang/crates.io-index" 1932 | checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909" 1933 | dependencies = [ 1934 | "libc", 1935 | "linux-raw-sys", 1936 | "rustix", 1937 | ] 1938 | 1939 | [[package]] 1940 | name = "yoke" 1941 | version = "0.7.5" 1942 | source = "registry+https://github.com/rust-lang/crates.io-index" 1943 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 1944 | dependencies = [ 1945 | "serde", 1946 | "stable_deref_trait", 1947 | "yoke-derive", 1948 | "zerofrom", 1949 | ] 1950 | 1951 | [[package]] 1952 | name = "yoke-derive" 1953 | version = "0.7.5" 1954 | source = "registry+https://github.com/rust-lang/crates.io-index" 1955 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 1956 | dependencies = [ 1957 | "proc-macro2", 1958 | "quote", 1959 | "syn 2.0.95", 1960 | "synstructure", 1961 | ] 1962 | 1963 | [[package]] 1964 | name = "zerocopy" 1965 | version = "0.7.35" 1966 | source = "registry+https://github.com/rust-lang/crates.io-index" 1967 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 1968 | dependencies = [ 1969 | "byteorder", 1970 | "zerocopy-derive", 1971 | ] 1972 | 1973 | [[package]] 1974 | name = "zerocopy-derive" 1975 | version = "0.7.35" 1976 | source = "registry+https://github.com/rust-lang/crates.io-index" 1977 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 1978 | dependencies = [ 1979 | "proc-macro2", 1980 | "quote", 1981 | "syn 2.0.95", 1982 | ] 1983 | 1984 | [[package]] 1985 | name = "zerofrom" 1986 | version = "0.1.5" 1987 | source = "registry+https://github.com/rust-lang/crates.io-index" 1988 | checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" 1989 | dependencies = [ 1990 | "zerofrom-derive", 1991 | ] 1992 | 1993 | [[package]] 1994 | name = "zerofrom-derive" 1995 | version = "0.1.5" 1996 | source = "registry+https://github.com/rust-lang/crates.io-index" 1997 | checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" 1998 | dependencies = [ 1999 | "proc-macro2", 2000 | "quote", 2001 | "syn 2.0.95", 2002 | "synstructure", 2003 | ] 2004 | 2005 | [[package]] 2006 | name = "zeroize" 2007 | version = "1.8.1" 2008 | source = "registry+https://github.com/rust-lang/crates.io-index" 2009 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 2010 | 2011 | [[package]] 2012 | name = "zerovec" 2013 | version = "0.10.4" 2014 | source = "registry+https://github.com/rust-lang/crates.io-index" 2015 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 2016 | dependencies = [ 2017 | "yoke", 2018 | "zerofrom", 2019 | "zerovec-derive", 2020 | ] 2021 | 2022 | [[package]] 2023 | name = "zerovec-derive" 2024 | version = "0.10.3" 2025 | source = "registry+https://github.com/rust-lang/crates.io-index" 2026 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 2027 | dependencies = [ 2028 | "proc-macro2", 2029 | "quote", 2030 | "syn 2.0.95", 2031 | ] 2032 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pcap_reader" 3 | version = "0.1.2" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | # crate-type = ["staticlib", "cdylib"] 9 | 10 | [profile.release] 11 | lto = true 12 | strip = true 13 | 14 | [[example]] 15 | # crate-type can't be (at the moment) be overriden for specific targets 16 | # src/wasm_lib.rs forwards to src/lib.rs so that we can change from cdylib 17 | # (that is needed while compiling natively) to staticlib (needed since the 18 | # actual linking will be done via emcc 19 | name = "pcap_reader" 20 | path = "src/wasm_lib.rs" 21 | crate-type = ["staticlib"] 22 | 23 | [dependencies] 24 | duckdb = { version = "1.2.2", features = ["vtab-loadable"] } 25 | duckdb-loadable-macros = "0.1.5" 26 | libduckdb-sys = { version = "1.2.2", features = ["loadable-extension"] } 27 | pcap-parser = "0.16.0" 28 | hex = "0.4" 29 | ehttp = "0.5.0" 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean clean_all 2 | 3 | PROJ_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 4 | 5 | # Set to 1 to enable Unstable API (binaries will only work on TARGET_DUCKDB_VERSION, forwards compatibility will be broken) 6 | # Note: currently extension-template-rs requires this, as duckdb-rs relies on unstable C API functionality 7 | USE_UNSTABLE_C_API=1 8 | 9 | # TODO: these values are currently duplicated in lib.rs. There's a PR open in duckdb-rs that fixes this 10 | EXTENSION_NAME=pcap_reader 11 | MINIMUM_DUCKDB_VERSION=v1.2.2 12 | TARGET_DUCKDB_VERSION=v1.2.2 13 | DUCKDB_EXTENSION_MIN_DUCKDB_VERSION=v1.2.2 14 | 15 | all: configure debug 16 | 17 | # Include makefiles from DuckDB 18 | include extension-ci-tools/makefiles/c_api_extensions/base.Makefile 19 | include extension-ci-tools/makefiles/c_api_extensions/rust.Makefile 20 | 21 | configure: venv platform extension_version 22 | 23 | debug: build_extension_library_debug build_extension_with_metadata_debug 24 | release: build_extension_library_release build_extension_with_metadata_release 25 | 26 | test: test_debug 27 | test_debug: test_extension_debug 28 | test_release: test_extension_release 29 | 30 | clean: clean_build clean_rust 31 | clean_all: clean_configure clean 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # DuckDB PCAP Community Extension 4 | This experimental rust extension allows reading PCAP files from DuckDB using the [pcap-parser crate](https://crates.io/crates/pcap-parser) 5 | 6 | > Experimental: USE AT YOUR OWN RISK! 7 | 8 | ### 📦 Installation 9 | ```sql 10 | INSTALL pcap_reader FROM community; 11 | LOAD pcap_reader; 12 | ``` 13 | 14 | ### Example 15 | ```sql 16 | D SELECT * FROM pcap_reader('test/test.pcap') LIMIT 3; 17 | ┌─────────────────────┬────────────────┬────────────────┬──────────┬──────────┬──────────┬────────┬───────────────────────────────────────────┐ 18 | │ timestamp │ src_ip │ dst_ip │ src_port │ dst_port │ protocol │ length │ payload │ 19 | │ timestamp │ varchar │ varchar │ int32 │ int32 │ varchar │ int32 │ varchar │ 20 | ├─────────────────────┼────────────────┼────────────────┼──────────┼──────────┼──────────┼────────┼───────────────────────────────────────────┤ 21 | │ 2024-12-06 19:30:2… │ xx.xx.xx.xxx │ yyy.yyy.yy.yyy │ 64078 │ 5080 │ UDP │ 756 │ INVITE sip:810442837619024@yyy.yyy.yy.y… │ 22 | │ 2024-12-06 19:30:2… │ yyy.yyy.yy.yyy │ xx.xx.xx.xxx │ 5080 │ 64078 │ UDP │ 360 │ SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP … │ 23 | │ 2024-12-06 19:30:2… │ yyy.yyy.yy.yyy │ xx.xx.xx.xxx │ 5080 │ 64078 │ UDP │ 909 │ SIP/2.0 480 Temporarily Unavailable\r\n… │ 24 | ├─────────────────────┴────────────────┴────────────────┴──────────┴──────────┴──────────┴────────┴───────────────────────────────────────────┤ 25 | │ 3 rows 8 columns │ 26 | └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ 27 | ``` 28 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate duckdb; 2 | extern crate duckdb_loadable_macros; 3 | extern crate libduckdb_sys; 4 | extern crate pcap_parser; 5 | 6 | use std::sync::{Arc, Mutex, atomic::{AtomicBool, Ordering}}; 7 | 8 | use duckdb::{ 9 | core::{DataChunkHandle, Inserter, LogicalTypeHandle, LogicalTypeId}, 10 | vtab::{BindInfo, InitInfo, TableFunctionInfo, VTab}, 11 | Connection, Result, 12 | }; 13 | use duckdb_loadable_macros::duckdb_entrypoint_c_api; 14 | use libduckdb_sys as ffi; 15 | use pcap_parser::traits::PcapReaderIterator; 16 | use pcap_parser::*; 17 | use std::{ 18 | error::Error, 19 | fs::File, 20 | io::{Cursor, Read}, 21 | }; 22 | 23 | macro_rules! debug_print { 24 | ($($arg:tt)*) => { 25 | if std::env::var("DEBUG").is_ok() { 26 | eprintln!("[PCAP Debug] {}", format!($($arg)*)); 27 | } 28 | }; 29 | } 30 | 31 | struct PcapBindData { 32 | filepath: String, 33 | } 34 | 35 | struct PcapReaderWrapper { 36 | reader: LegacyPcapReader>, 37 | } 38 | 39 | struct PcapInitData { 40 | reader: Arc>>, 41 | done: AtomicBool, 42 | } 43 | 44 | struct PcapVTab; 45 | 46 | impl VTab for PcapVTab { 47 | type InitData = PcapInitData; 48 | type BindData = PcapBindData; 49 | 50 | fn bind(bind: &BindInfo) -> Result> { 51 | bind.add_result_column( 52 | "timestamp", 53 | LogicalTypeHandle::from(LogicalTypeId::Timestamp), 54 | ); 55 | bind.add_result_column("src_ip", LogicalTypeHandle::from(LogicalTypeId::Varchar)); 56 | bind.add_result_column("dst_ip", LogicalTypeHandle::from(LogicalTypeId::Varchar)); 57 | bind.add_result_column("src_port", LogicalTypeHandle::from(LogicalTypeId::Integer)); 58 | bind.add_result_column("dst_port", LogicalTypeHandle::from(LogicalTypeId::Integer)); 59 | bind.add_result_column( 60 | "protocol", 61 | LogicalTypeHandle::from(LogicalTypeId::Varchar), 62 | ); 63 | bind.add_result_column("length", LogicalTypeHandle::from(LogicalTypeId::Integer)); 64 | bind.add_result_column("payload", LogicalTypeHandle::from(LogicalTypeId::Varchar)); 65 | 66 | let filepath = bind.get_parameter(0).to_string(); 67 | 68 | Ok(PcapBindData { 69 | filepath, 70 | }) 71 | } 72 | 73 | // Initialize the VTab 74 | fn init(info: &InitInfo) -> Result> { 75 | let bind_data = info.get_bind_data::(); 76 | let filepath = unsafe { (*bind_data).filepath.clone() }; 77 | 78 | debug_print!("Opening file: {}", filepath); 79 | 80 | let reader: Box = 81 | if filepath.starts_with("http://") || filepath.starts_with("https://") { 82 | debug_print!("Using HTTP reader for {}", filepath); 83 | 84 | // Create a channel to receive the response 85 | let (tx, rx) = std::sync::mpsc::channel(); 86 | 87 | let request = ehttp::Request::get(filepath); 88 | ehttp::fetch(request, move |result: ehttp::Result| { 89 | tx.send(result).unwrap(); 90 | }); 91 | 92 | // Wait for the response 93 | let response = rx 94 | .recv()? 95 | .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?; 96 | Box::new(Cursor::new(response.bytes)) 97 | } else { 98 | debug_print!("Using file reader for {}", filepath); 99 | Box::new(File::open(filepath)?) 100 | }; 101 | 102 | // Create the pcap reader 103 | let pcap_reader = LegacyPcapReader::new(65536, reader).expect("PcapReader"); 104 | 105 | let reader_wrapper = PcapReaderWrapper { 106 | reader: pcap_reader, 107 | }; 108 | 109 | Ok(PcapInitData { 110 | reader: Arc::new(Mutex::new(Some(reader_wrapper))), 111 | done: AtomicBool::new(false), 112 | }) 113 | } 114 | 115 | fn func( 116 | func: &TableFunctionInfo, 117 | output: &mut DataChunkHandle, 118 | ) -> Result<(), Box> { 119 | let init_data = func.get_init_data(); 120 | 121 | // Check if we're done 122 | if init_data.done.load(Ordering::Relaxed) { 123 | output.set_len(0); 124 | return Ok(()); 125 | } 126 | 127 | let mut count = 0; 128 | let mut reached_eof = false; 129 | let mut packet_data = None; 130 | 131 | // First, process a block with careful locking 132 | { 133 | let mut reader_guard = match init_data.reader.lock() { 134 | Ok(guard) => guard, 135 | Err(_) => return Err("Failed to lock reader".into()), 136 | }; 137 | 138 | let reader_wrapper = match reader_guard.as_mut() { 139 | Some(wrapper) => wrapper, 140 | None => return Err("Reader is not initialized".into()), 141 | }; 142 | 143 | debug_print!("Attempting to read from PCAP file"); 144 | 145 | // Process in a loop until we find a valid packet or reach EOF 146 | 'packet_loop: loop { 147 | // Try to get a meaningful block 148 | let block_result = reader_wrapper.reader.next(); 149 | 150 | match block_result { 151 | Ok((offset, block)) => { 152 | debug_print!("Got a block, examining it"); 153 | match block { 154 | // If we have a packet, extract the data from it 155 | PcapBlockOwned::Legacy(packet) => { 156 | debug_print!("Found a Legacy packet"); 157 | let ts_micros = packet.ts_sec as i64 * 1_000_000 + packet.ts_usec as i64; 158 | let parsed_result = Self::parse_packet(&packet.data); 159 | 160 | if let Ok((src_ip, dst_ip, src_port, dst_port, l4_protocol, payload)) = parsed_result { 161 | debug_print!("Successfully parsed packet"); 162 | // Store all the packet info for processing outside the lock 163 | packet_data = Some(( 164 | ts_micros, 165 | src_ip, 166 | dst_ip, 167 | src_port, 168 | dst_port, 169 | l4_protocol, 170 | packet.origlen, 171 | payload 172 | )); 173 | 174 | // Consume the block and exit the loop - we found a valid packet 175 | reader_wrapper.reader.consume(offset); 176 | break 'packet_loop; 177 | } else { 178 | debug_print!("Failed to parse packet"); 179 | // Error parsing packet, just consume and continue 180 | reader_wrapper.reader.consume(offset); 181 | } 182 | }, 183 | PcapBlockOwned::LegacyHeader(header) => { 184 | debug_print!("Found a Legacy header: version={}.{}", 185 | header.version_major, header.version_minor); 186 | reader_wrapper.reader.consume(offset); 187 | }, 188 | // Skip other blocks 189 | _ => { 190 | debug_print!("Found some other type of block"); 191 | reader_wrapper.reader.consume(offset); 192 | } 193 | } 194 | }, 195 | Err(PcapError::Incomplete(needed)) => { 196 | debug_print!("Incomplete data, need {} more bytes, trying to refill", needed); 197 | // Need to refill 198 | if let Err(e) = reader_wrapper.reader.refill() { 199 | debug_print!("Failed to refill: {:?}", e); 200 | reached_eof = true; 201 | break 'packet_loop; 202 | } else { 203 | debug_print!("Refilled successfully"); 204 | } 205 | }, 206 | Err(PcapError::Eof) => { 207 | debug_print!("Reached EOF"); 208 | reached_eof = true; 209 | break 'packet_loop; 210 | }, 211 | Err(e) => { 212 | debug_print!("Error reading PCAP: {:?}", e); 213 | reached_eof = true; 214 | break 'packet_loop; 215 | } 216 | } 217 | } 218 | } 219 | 220 | // Handle EOF outside the lock 221 | if reached_eof { 222 | init_data.done.store(true, Ordering::Relaxed); 223 | output.set_len(0); 224 | return Ok(()); 225 | } 226 | 227 | // Process packet data outside the lock 228 | if let Some((timestamp_micros, src_ip, dst_ip, src_port, dst_port, l4_protocol, packet_len, payload)) = packet_data { 229 | debug_print!( 230 | "Processing packet: timestamp={}, src={}:{}, dst={}:{}, proto={}, len={}", 231 | timestamp_micros, 232 | src_ip, 233 | src_port, 234 | dst_ip, 235 | dst_port, 236 | l4_protocol, 237 | packet_len 238 | ); 239 | 240 | // Fill the output vectors with packet data 241 | output.flat_vector(0).as_mut_slice::()[count] = timestamp_micros; 242 | output.flat_vector(1).insert(count, src_ip.as_str()); 243 | output.flat_vector(2).insert(count, dst_ip.as_str()); 244 | output.flat_vector(3).as_mut_slice::()[count] = src_port as i32; 245 | output.flat_vector(4).as_mut_slice::()[count] = dst_port as i32; 246 | output.flat_vector(5).insert(count, l4_protocol.as_str()); 247 | output.flat_vector(6).as_mut_slice::()[count] = packet_len as i32; 248 | 249 | // Process the payload for display 250 | let payload_str = if !payload.is_empty() { 251 | if let Ok(utf8_str) = std::str::from_utf8(&payload) { 252 | if utf8_str 253 | .chars() 254 | .all(|c| c.is_ascii_graphic() || c.is_ascii_whitespace()) 255 | { 256 | format!("{}", utf8_str) 257 | } else { 258 | let hex_str: Vec = payload 259 | .iter() 260 | .take(32) 261 | .map(|b| format!("{:02x}", b)) 262 | .collect(); 263 | format!( 264 | "{}{}", 265 | hex_str.join(" "), 266 | if payload.len() > 32 { " ..." } else { "" } 267 | ) 268 | } 269 | } else { 270 | let hex_str: Vec = payload 271 | .iter() 272 | .take(32) 273 | .map(|b| format!("{:02x}", b)) 274 | .collect(); 275 | format!( 276 | "{}{}", 277 | hex_str.join(" "), 278 | if payload.len() > 32 { " ..." } else { "" } 279 | ) 280 | } 281 | } else { 282 | "empty".to_string() 283 | }; 284 | output.flat_vector(7).insert(count, payload_str.as_str()); 285 | 286 | count += 1; 287 | } 288 | 289 | // Set the number of rows in the output 290 | output.set_len(count); 291 | Ok(()) 292 | } 293 | 294 | fn parameters() -> Option> { 295 | Some(vec![LogicalTypeHandle::from(LogicalTypeId::Varchar)]) 296 | } 297 | } 298 | 299 | impl PcapVTab { 300 | /* 301 | function parse_packet 302 | Return the source IP, destination IP, source port, destination port, L4 protocol, payload 303 | */ 304 | fn parse_packet( 305 | data: &[u8], 306 | ) -> Result<(String, String, u16, u16, String, Vec), Box> { 307 | let mut src_ip = String::from("0.0.0.0"); 308 | let mut dst_ip = String::from("0.0.0.0"); 309 | let mut src_port = 0; 310 | let mut dst_port = 0; 311 | let mut l4_protocol = String::from("UNKNOWN"); 312 | let mut payload = Vec::new(); 313 | 314 | debug_print!("Parsing packet of length: {}", data.len()); 315 | 316 | // Parse the Ethernet header 317 | if data.len() >= 14 { 318 | let ethertype = u16::from_be_bytes([data[12], data[13]]); 319 | debug_print!("Ethertype: 0x{:04x}", ethertype); 320 | 321 | let mut transport_header_start = 0; 322 | let mut ip_protocol = 0; 323 | 324 | // Parse the IP header 325 | if ethertype == 0x0800 && data.len() >= 34 { 326 | let ip_header_len = (data[14] & 0x0f) * 4; 327 | debug_print!("IP header length: {}", ip_header_len); 328 | 329 | src_ip = format!("{}.{}.{}.{}", data[26], data[27], data[28], data[29]); 330 | dst_ip = format!("{}.{}.{}.{}", data[30], data[31], data[32], data[33]); 331 | 332 | ip_protocol = data[23]; 333 | debug_print!("IP Protocol: {}", ip_protocol); 334 | 335 | transport_header_start = 14 + ip_header_len as usize; 336 | } 337 | // Parse the IPv6 header 338 | else if ethertype == 0x86DD && data.len() >= 54 { 339 | let ip_header_len = 54; 340 | debug_print!("IPv6 header length: {}", ip_header_len); 341 | 342 | src_ip = format!( 343 | "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", 344 | u16::from_be_bytes([data[22], data[23]]), 345 | u16::from_be_bytes([data[24], data[25]]), 346 | u16::from_be_bytes([data[26], data[27]]), 347 | u16::from_be_bytes([data[28], data[29]]), 348 | u16::from_be_bytes([data[30], data[31]]), 349 | u16::from_be_bytes([data[32], data[33]]), 350 | u16::from_be_bytes([data[34], data[35]]), 351 | u16::from_be_bytes([data[36], data[37]]) 352 | ); 353 | dst_ip = format!( 354 | "{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}", 355 | u16::from_be_bytes([data[38], data[39]]), 356 | u16::from_be_bytes([data[40], data[41]]), 357 | u16::from_be_bytes([data[42], data[43]]), 358 | u16::from_be_bytes([data[44], data[45]]), 359 | u16::from_be_bytes([data[46], data[47]]), 360 | u16::from_be_bytes([data[48], data[49]]), 361 | u16::from_be_bytes([data[50], data[51]]), 362 | u16::from_be_bytes([data[52], data[53]]) 363 | ); 364 | 365 | ip_protocol = data[20]; 366 | debug_print!("IP protocol: {}", ip_protocol); 367 | 368 | transport_header_start = ip_header_len as usize; 369 | } 370 | 371 | // Parse the transport header 372 | match ip_protocol { 373 | 6 => { 374 | l4_protocol = String::from("TCP"); 375 | if data.len() >= transport_header_start + 4 { 376 | src_port = u16::from_be_bytes([ 377 | data[transport_header_start], 378 | data[transport_header_start + 1], 379 | ]); 380 | debug_print!("TCP Source Port: {}", src_port); 381 | dst_port = u16::from_be_bytes([ 382 | data[transport_header_start + 2], 383 | data[transport_header_start + 3], 384 | ]); 385 | debug_print!("TCP Destination Port: {}", dst_port); 386 | } 387 | } 388 | 17 => { 389 | l4_protocol = String::from("UDP"); 390 | if data.len() >= transport_header_start + 4 { 391 | src_port = u16::from_be_bytes([ 392 | data[transport_header_start], 393 | data[transport_header_start + 1], 394 | ]); 395 | debug_print!("UDP Source Port: {}", src_port); 396 | dst_port = u16::from_be_bytes([ 397 | data[transport_header_start + 2], 398 | data[transport_header_start + 3], 399 | ]); 400 | debug_print!("UDP Destination Port: {}", dst_port); 401 | } 402 | } 403 | _ => l4_protocol = format!("IP({})", ip_protocol), 404 | } 405 | 406 | // Parse the payload 407 | let payload_start = transport_header_start 408 | + match ip_protocol { 409 | 6 => 20, 410 | 17 => 8, 411 | _ => 0, 412 | }; 413 | 414 | // Copy the payload 415 | if data.len() > payload_start { 416 | payload = data[payload_start..].to_vec(); 417 | } 418 | } 419 | 420 | // Print the parsed packet 421 | debug_print!( 422 | "Parsed packet: {}:{} -> {}:{} ({})", 423 | src_ip, 424 | src_port, 425 | dst_ip, 426 | dst_port, 427 | l4_protocol 428 | ); 429 | 430 | // Return the parsed packet 431 | Ok((src_ip, dst_ip, src_port, dst_port, l4_protocol, payload)) 432 | } 433 | } 434 | 435 | #[duckdb_entrypoint_c_api(ext_name = "pcap_reader", min_duckdb_version = "v1.2.0")] 436 | pub fn extension_entrypoint(con: Connection) -> Result<(), Box> { 437 | // Print a simple load message (could be controlled with a verbose flag if needed) 438 | debug_print!("Loading PCAP reader extension"); 439 | 440 | con.register_table_function::("pcap_reader") 441 | .expect("Failed to register pcap_reader function"); 442 | 443 | Ok(()) 444 | } 445 | -------------------------------------------------------------------------------- /src/wasm_lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(special_module_name)] 2 | 3 | mod lib; 4 | 5 | // To build the Wasm target, a `staticlib` crate-type is required 6 | // 7 | // This is different than the default needed in native, and there is 8 | // currently no way to select crate-type depending on target. 9 | // 10 | // This file sole purpose is remapping the content of lib as an 11 | // example, do not change the content of the file. 12 | // 13 | // To build the Wasm target explicitly, use: 14 | // cargo build --example $PACKAGE_NAME 15 | -------------------------------------------------------------------------------- /test/sql/pcap_reader.test: -------------------------------------------------------------------------------- 1 | # name: test/sql/rusty_quack.test 2 | # description: test rusty_quack extension 3 | # group: [quack] 4 | 5 | # Before we load the extension, this will fail 6 | statement error 7 | SELECT pcap_reader('./test/test.pcap'); 8 | ---- 9 | Catalog Error: Scalar Function with name pcap_reader does not exist! 10 | 11 | # Require statement will ensure the extension is loaded from now on 12 | require pcap_reader 13 | 14 | require icu 15 | 16 | # Confirm the extension works 17 | query I 18 | SELECT count(*) as count from pcap_reader('./test/test.pcap'); 19 | ---- 20 | 12 21 | -------------------------------------------------------------------------------- /test/test.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quackscience/duckdb-extension-pcap/a7f4900e4c640e12f17f0980a59c59876b620802/test/test.pcap --------------------------------------------------------------------------------