├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── cubostratus.png ├── cubostratusc.toml └── src ├── aggregator.rs ├── bin └── bin.rs ├── collector.rs ├── config.rs ├── error.rs ├── lib.rs ├── state ├── cgroups.rs ├── fd.rs ├── mod.rs ├── net.rs ├── parsers.rs └── thread.rs ├── syscall ├── mod.rs └── syscall_table.rs └── value.rs /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | target/ 3 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "cubostratusc" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "chrono 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "kafka 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 8 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 9 | "nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 10 | "nom 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 11 | "num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 12 | "serde 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)", 13 | "serde_derive 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", 15 | "toml 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 16 | ] 17 | 18 | [[package]] 19 | name = "bitflags" 20 | version = "0.4.0" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | 23 | [[package]] 24 | name = "bitflags" 25 | version = "0.7.0" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | 28 | [[package]] 29 | name = "byteorder" 30 | version = "0.5.3" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | 33 | [[package]] 34 | name = "cfg-if" 35 | version = "0.1.0" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | 38 | [[package]] 39 | name = "chrono" 40 | version = "0.3.0" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | dependencies = [ 43 | "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 44 | "serde 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)", 45 | "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", 46 | ] 47 | 48 | [[package]] 49 | name = "crc" 50 | version = "1.4.0" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | dependencies = [ 53 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 54 | ] 55 | 56 | [[package]] 57 | name = "dtoa" 58 | version = "0.4.1" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | 61 | [[package]] 62 | name = "flate2" 63 | version = "0.2.19" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | dependencies = [ 66 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 67 | "miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 68 | ] 69 | 70 | [[package]] 71 | name = "fnv" 72 | version = "1.0.5" 73 | source = "registry+https://github.com/rust-lang/crates.io-index" 74 | 75 | [[package]] 76 | name = "gcc" 77 | version = "0.3.45" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | 80 | [[package]] 81 | name = "gdi32-sys" 82 | version = "0.2.0" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | dependencies = [ 85 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 86 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 87 | ] 88 | 89 | [[package]] 90 | name = "glob" 91 | version = "0.2.11" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | 94 | [[package]] 95 | name = "itoa" 96 | version = "0.3.1" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | 99 | [[package]] 100 | name = "kafka" 101 | version = "0.5.0" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | dependencies = [ 104 | "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 105 | "crc 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 106 | "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", 107 | "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 108 | "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 109 | "openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", 110 | "ref_slice 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 111 | "snappy 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 112 | ] 113 | 114 | [[package]] 115 | name = "kernel32-sys" 116 | version = "0.2.2" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | dependencies = [ 119 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 120 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 121 | ] 122 | 123 | [[package]] 124 | name = "lazy_static" 125 | version = "0.2.8" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | 128 | [[package]] 129 | name = "libc" 130 | version = "0.2.21" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | 133 | [[package]] 134 | name = "libressl-pnacl-sys" 135 | version = "2.1.6" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | dependencies = [ 138 | "pnacl-build-helper 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)", 139 | ] 140 | 141 | [[package]] 142 | name = "log" 143 | version = "0.3.7" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | 146 | [[package]] 147 | name = "miniz-sys" 148 | version = "0.1.9" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | dependencies = [ 151 | "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", 152 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 153 | ] 154 | 155 | [[package]] 156 | name = "nix" 157 | version = "0.7.0" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | dependencies = [ 160 | "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 161 | "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 162 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 163 | "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 164 | "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", 165 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 166 | ] 167 | 168 | [[package]] 169 | name = "nom" 170 | version = "2.2.1" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | 173 | [[package]] 174 | name = "num" 175 | version = "0.1.37" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | dependencies = [ 178 | "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", 179 | "num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", 180 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 181 | ] 182 | 183 | [[package]] 184 | name = "num-integer" 185 | version = "0.1.34" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | dependencies = [ 188 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 189 | ] 190 | 191 | [[package]] 192 | name = "num-iter" 193 | version = "0.1.33" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | dependencies = [ 196 | "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", 197 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 198 | ] 199 | 200 | [[package]] 201 | name = "num-traits" 202 | version = "0.1.37" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | 205 | [[package]] 206 | name = "num_cpus" 207 | version = "1.3.0" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | dependencies = [ 210 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 211 | ] 212 | 213 | [[package]] 214 | name = "openssl" 215 | version = "0.7.14" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | dependencies = [ 218 | "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 219 | "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", 220 | "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 221 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 222 | "openssl-sys 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)", 223 | "openssl-sys-extras 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)", 224 | ] 225 | 226 | [[package]] 227 | name = "openssl-sys" 228 | version = "0.7.17" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | dependencies = [ 231 | "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 232 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 233 | "libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 234 | "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 235 | "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 236 | ] 237 | 238 | [[package]] 239 | name = "openssl-sys-extras" 240 | version = "0.7.14" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | dependencies = [ 243 | "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", 244 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 245 | "openssl-sys 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)", 246 | ] 247 | 248 | [[package]] 249 | name = "pkg-config" 250 | version = "0.3.9" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | 253 | [[package]] 254 | name = "pnacl-build-helper" 255 | version = "1.4.11" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | dependencies = [ 258 | "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 259 | "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 260 | ] 261 | 262 | [[package]] 263 | name = "quote" 264 | version = "0.3.15" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | 267 | [[package]] 268 | name = "rand" 269 | version = "0.3.15" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | dependencies = [ 272 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 273 | ] 274 | 275 | [[package]] 276 | name = "redox_syscall" 277 | version = "0.1.17" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | 280 | [[package]] 281 | name = "ref_slice" 282 | version = "1.1.1" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | 285 | [[package]] 286 | name = "rustc_version" 287 | version = "0.1.7" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | dependencies = [ 290 | "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", 291 | ] 292 | 293 | [[package]] 294 | name = "same-file" 295 | version = "0.1.3" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | dependencies = [ 298 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 299 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 300 | ] 301 | 302 | [[package]] 303 | name = "semver" 304 | version = "0.1.20" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | 307 | [[package]] 308 | name = "serde" 309 | version = "0.9.13" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | 312 | [[package]] 313 | name = "serde_codegen_internals" 314 | version = "0.14.2" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | dependencies = [ 317 | "syn 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", 318 | ] 319 | 320 | [[package]] 321 | name = "serde_derive" 322 | version = "0.9.13" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | dependencies = [ 325 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 326 | "serde_codegen_internals 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)", 327 | "syn 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", 328 | ] 329 | 330 | [[package]] 331 | name = "serde_json" 332 | version = "0.9.10" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | dependencies = [ 335 | "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 336 | "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 337 | "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 338 | "serde 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)", 339 | ] 340 | 341 | [[package]] 342 | name = "snappy" 343 | version = "0.3.0" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | dependencies = [ 346 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 347 | "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 348 | ] 349 | 350 | [[package]] 351 | name = "syn" 352 | version = "0.11.10" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | dependencies = [ 355 | "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 356 | "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", 357 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 358 | ] 359 | 360 | [[package]] 361 | name = "synom" 362 | version = "0.11.3" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | dependencies = [ 365 | "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 366 | ] 367 | 368 | [[package]] 369 | name = "tempdir" 370 | version = "0.3.5" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | dependencies = [ 373 | "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 374 | ] 375 | 376 | [[package]] 377 | name = "time" 378 | version = "0.1.36" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | dependencies = [ 381 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 382 | "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", 383 | "redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", 384 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 385 | ] 386 | 387 | [[package]] 388 | name = "toml" 389 | version = "0.3.2" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | dependencies = [ 392 | "serde 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)", 393 | ] 394 | 395 | [[package]] 396 | name = "unicode-xid" 397 | version = "0.0.4" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | 400 | [[package]] 401 | name = "user32-sys" 402 | version = "0.2.0" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | dependencies = [ 405 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 406 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 407 | ] 408 | 409 | [[package]] 410 | name = "void" 411 | version = "1.0.2" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | 414 | [[package]] 415 | name = "walkdir" 416 | version = "1.0.7" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | dependencies = [ 419 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 420 | "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 421 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 422 | ] 423 | 424 | [[package]] 425 | name = "winapi" 426 | version = "0.2.8" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | 429 | [[package]] 430 | name = "winapi-build" 431 | version = "0.1.1" 432 | source = "registry+https://github.com/rust-lang/crates.io-index" 433 | 434 | [metadata] 435 | "checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" 436 | "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" 437 | "checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" 438 | "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" 439 | "checksum chrono 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "158b0bd7d75cbb6bf9c25967a48a2e9f77da95876b858eadfabaa99cd069de6e" 440 | "checksum crc 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc1914fae6f18ae347320f0ba5e4fc270e17c037ea621fe41ec7e8adf67d11b0" 441 | "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" 442 | "checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c" 443 | "checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344" 444 | "checksum gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)" = "40899336fb50db0c78710f53e87afc54d8c7266fb76262fecc78ca1a7f09deae" 445 | "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" 446 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 447 | "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" 448 | "checksum kafka 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3614794fd04ebccbbf1e89105a2432d4c622754f848a4f769656875e966296" 449 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 450 | "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" 451 | "checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" 452 | "checksum libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "cbc058951ab6a3ef35ca16462d7642c4867e6403520811f28537a4e2f2db3e71" 453 | "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" 454 | "checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726" 455 | "checksum nix 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0d95c5fa8b641c10ad0b8887454ebaafa3c92b5cd5350f8fc693adafd178e7b" 456 | "checksum nom 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" 457 | "checksum num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "98b15ba84e910ea7a1973bccd3df7b31ae282bf9d8bd2897779950c9b8303d40" 458 | "checksum num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1a4bf6f9174aa5783a9b4cc892cacd11aebad6c69ad027a0b65c6ca5f8aa37" 459 | "checksum num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d1891bd7b936f12349b7d1403761c8a0b85a18b148e9da4429d5d102c1a41e" 460 | "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" 461 | "checksum num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18c392466409c50b87369414a2680c93e739aedeb498eb2bff7d7eb569744e2" 462 | "checksum openssl 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "c4117b6244aac42ed0150a6019b4d953d28247c5dd6ae6f46ae469b5f2318733" 463 | "checksum openssl-sys 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)" = "89c47ee94c352eea9ddaf8e364be7f978a3bb6d66d73176572484238dd5a5c3f" 464 | "checksum openssl-sys-extras 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "11c5e1dba7d3d03d80f045bf0d60111dc69213b67651e7c889527a3badabb9fa" 465 | "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" 466 | "checksum pnacl-build-helper 1.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dfbe13ee77c06fb633d71c72438bd983286bb3521863a753ade8e951c7efb090" 467 | "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" 468 | "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" 469 | "checksum redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "29dbdfd4b9df8ab31dec47c6087b7b13cbf4a776f335e4de8efba8288dda075b" 470 | "checksum ref_slice 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "825740057197b7d43025e7faf6477eaabc03434e153233da02d1f44602f71527" 471 | "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" 472 | "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" 473 | "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" 474 | "checksum serde 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "231dfd55909400769e437326cfb4af8bec97c3dd56ab3d02df8ef5c7e00f179b" 475 | "checksum serde_codegen_internals 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc888bd283bd2420b16ad0d860e35ad8acb21941180a83a189bb2046f9d00400" 476 | "checksum serde_derive 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "d75c72ef4dd193d89eb652b73890fe2489996c9ead8b37980f57a1078f96ed50" 477 | "checksum serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ad8bcf487be7d2e15d3d543f04312de991d631cfe1b43ea0ade69e6a8a5b16a1" 478 | "checksum snappy 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17d70c85c3299944adf664d5c8690cc854780180391a38866856b7187da28a2f" 479 | "checksum syn 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)" = "171b739972d9a1bfb169e8077238b51f9ebeaae4ff6e08072f7ba386a8802da2" 480 | "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" 481 | "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" 482 | "checksum time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "211b63c112206356ef1ff9b19355f43740fc3f85960c598a93d3a3d3ba7beade" 483 | "checksum toml 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd86ad9ebee246fdedd610e0f6d0587b754a3d81438db930a244d0480ed7878f" 484 | "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" 485 | "checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" 486 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 487 | "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" 488 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 489 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 490 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cubostratusc" 3 | version = "0.1.0" 4 | authors = ["Nedim Šabić "] 5 | description = "Blazingly fast Linux syscall collector" 6 | 7 | [lib] 8 | name = "cubostratusc" 9 | path = "src/lib.rs" 10 | 11 | [[bin]] 12 | name = "cubostratusc" 13 | path = "src/bin/bin.rs" 14 | 15 | [dependencies] 16 | nix = "0.7.0" 17 | libc = "0.2.20" 18 | num_cpus = "1.2.1" 19 | chrono = { version = "0.3.0", features = ["serde"] } 20 | nom = { version = "2.2.1", features = ["verbose-errors"] } 21 | serde = "0.9" 22 | serde_derive = "0.9" 23 | serde_json = "0.9" 24 | kafka = "0.5" 25 | toml = "0.3.1" 26 | glob = "0.2.11" 27 | 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | **cubostratus** is a high performance Linux syscall collector. It acquires the syscall flow from the rock solid [sysdig](https://github.com/draios/sysdig) driver and emits it to Kafka brokers for later ingestion, storage and analysis. 6 | 7 | # Usage 8 | 9 | 1. Build the sysdig kernel module or [install](http://www.sysdig.org/install/) sysdig 10 | 2. Install Rust 11 | ```bash 12 | curl -f -L https://static.rust-lang.org/rustup.sh -O 13 | sh rustup.sh 14 | ``` 15 | 3. Clone this repository and build `cubostratusc` 16 | ```bash 17 | git clone https://github.com/rabbitstack/cubostratusc.git 18 | cd cubostratusc 19 | cargo build 20 | ```` 21 | 4. Modify `cubostratusc.toml` configuration descriptor 22 | ```bash 23 | export CUBOSTRATUSC_CONFIG=cubostratusc.toml # or 24 | sudo cp cubostratusc.toml /etc 25 | ``` 26 | 5. Create a `Kafka` topic and start `cubostratusc`: 27 | ```bash 28 | bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 \ 29 | --partitions 1 --topic cubostratus 30 | sudo ./target/debug/cubostratusc 31 | ``` 32 | -------------------------------------------------------------------------------- /cubostratus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rabbitstack/cubostratus/3a55efbf0cd41931016365605e6f35bbc3f1c6b8/cubostratus.png -------------------------------------------------------------------------------- /cubostratusc.toml: -------------------------------------------------------------------------------- 1 | [kafka] 2 | hosts = ["localhost:8092"] 3 | topic = "cubostratus" 4 | ack_timeout = 1 -------------------------------------------------------------------------------- /src/aggregator.rs: -------------------------------------------------------------------------------- 1 | //! Syscall's stream aggregators used to ingest the flow of syscall events from the collector 2 | //! to messaging systems. 3 | use std::time::Duration; 4 | use kafka::producer::{Producer, Record, RequiredAcks}; 5 | use kafka; 6 | use config::KafkaConfig; 7 | 8 | pub trait Aggregator { 9 | 10 | fn do_aggregate(&mut self, body: T); 11 | } 12 | 13 | pub struct KafkaAggregator { 14 | /// an instance of the Kafka producer 15 | producer: Option, 16 | /// kafka configuration 17 | config: KafkaConfig 18 | } 19 | 20 | /// Implementation of the syscall's aggregator which emits the stream of syscall events 21 | /// to Kafka brokers. 22 | impl Aggregator for KafkaAggregator { 23 | 24 | fn do_aggregate(&mut self, body: String) { 25 | match self.producer { 26 | Some(ref mut p) => { 27 | p.send(&Record::from_value(&self.config.topic, body.as_bytes())).unwrap(); 28 | } 29 | None => {} 30 | } 31 | } 32 | } 33 | 34 | impl KafkaAggregator { 35 | 36 | pub fn new(config: KafkaConfig) -> KafkaAggregator { 37 | KafkaAggregator { 38 | producer: None, 39 | config: config 40 | } 41 | } 42 | 43 | pub fn start(&mut self) -> Result<(), kafka::Error> { 44 | self.producer = match Producer::from_hosts(self.config.hosts.clone()) 45 | .with_ack_timeout(Duration::from_secs(self.config.ack_timeout)) 46 | .create() { 47 | Ok(p) => Some(p), 48 | Err(e) => return Err(e) 49 | }; 50 | Ok(()) 51 | } 52 | } -------------------------------------------------------------------------------- /src/bin/bin.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate serde_derive; 3 | extern crate serde_json; 4 | 5 | extern crate cubostratusc; 6 | 7 | use std::default::Default; 8 | use std::process; 9 | 10 | use cubostratusc::collector::Collector; 11 | use cubostratusc::collector::RingBufferCollector; 12 | use cubostratusc::syscall::syscall_table::SyscallTable; 13 | use cubostratusc::aggregator::{Aggregator, KafkaAggregator}; 14 | use cubostratusc::config; 15 | 16 | fn main() { 17 | 18 | let syscall_table = SyscallTable::default(); 19 | 20 | let config = match config::read_config() { 21 | Ok(config) => config, 22 | Err(e) => { 23 | exit_process(e.to_string()); 24 | } 25 | }; 26 | 27 | let mut aggregator = KafkaAggregator::new(config.kafka); 28 | match aggregator.start() { 29 | Ok(()) => {}, 30 | Err(e) => { 31 | exit_process(e.to_string()); 32 | } 33 | } 34 | 35 | let mut collector = RingBufferCollector::new(); 36 | match collector.start() { 37 | Ok(num_devs) => { 38 | loop { 39 | match collector.next() { 40 | Some(syscall_info) => { 41 | let json = serde_json::to_string(&syscall_info).unwrap(); 42 | aggregator.do_aggregate(json); 43 | }, 44 | None => {} 45 | } 46 | } 47 | }, 48 | Err(e) => { 49 | exit_process(e.to_string()); 50 | } 51 | } 52 | } 53 | 54 | fn exit_process(e: String) -> ! { 55 | println!("{}", e); 56 | process::exit(0) 57 | } -------------------------------------------------------------------------------- /src/collector.rs: -------------------------------------------------------------------------------- 1 | ///! Encapsulates the implementation of the syscall collectors. 2 | 3 | use libc; 4 | use num_cpus; 5 | use chrono::{NaiveDateTime, DateTime, UTC, TimeZone}; 6 | use nix::Error as NixError; 7 | use nix::errno; 8 | use nix::fcntl::{open, O_RDWR, O_SYNC}; 9 | use nix::unistd::close; 10 | use nix::sys::stat::S_IRUSR; 11 | use nix::sys::mman::{mmap, munmap}; 12 | use nix::sys::mman::{MAP_SHARED, PROT_READ, PROT_WRITE}; 13 | use std::ptr; 14 | use std::mem::size_of; 15 | 16 | use syscall::{Syscall, SyscallInfo}; 17 | use syscall::syscall_table::SyscallTable; 18 | use error::{Error, Result}; 19 | 20 | const RING_BUF_SIZE: usize = 8 * 1024 * 1024; 21 | const BUFFER_EMPTY_WAIT_TIME_MS: u32 = 30; 22 | const MAX_N_CONSECUTIVE_WAITS: usize = 4; 23 | 24 | const PPM_IOCTL_MAGIC: u8 = 's' as u8; 25 | const PPM_IOCTL_DISABLE_CAPTURE: u8 = 1; 26 | const PPM_IOCTL_ENABLE_CAPTURE: u8 = 1; 27 | 28 | 29 | ioctl!(none ioctl_start with PPM_IOCTL_MAGIC, PPM_IOCTL_ENABLE_CAPTURE); 30 | ioctl!(none ioctl_stop with PPM_IOCTL_MAGIC, PPM_IOCTL_DISABLE_CAPTURE); 31 | 32 | 33 | #[repr(C)] 34 | struct RingBufferInfo { 35 | head: u32, 36 | tail: u32, 37 | num_syscalls: u64, 38 | num_drops_buffer: u64, 39 | num_drops_pf: u64, 40 | num_preemptions: u64, 41 | num_context_switches: u64 42 | } 43 | 44 | struct RingBufferDev { 45 | fd: i32, 46 | buffer: *mut libc::c_char, 47 | buffer_info: *mut RingBufferInfo, 48 | last_readsize: u32, 49 | next_syscall: *mut libc::c_char, 50 | len: u32 51 | } 52 | 53 | pub trait Collector { 54 | fn start(&mut self) -> Result; 55 | 56 | fn stop(&mut self) -> Result<()>; 57 | 58 | fn next(&mut self) -> Option; 59 | } 60 | 61 | pub struct RingBufferCollector { 62 | devs: Vec, 63 | consecutive_waits: usize, 64 | syscall_table: SyscallTable 65 | } 66 | 67 | /// The implementation of the syscall collector based on the 68 | /// Sysdig's rock solid kernel driver. The driver uses circular / ring 69 | /// buffer data structure to publish the intercepted system calls from the 70 | /// kernel space. This aims to provide extremely high throughput and efficiency. 71 | impl Collector for RingBufferCollector { 72 | /// Opens the available ring buffer devices and maps the corresponding 73 | /// buffer content and the buffer information to a memory region 74 | /// of the calling thread. 75 | /// 76 | /// If the previous operations are done successfully, it sends the 77 | /// IO code to the underlying device to start the capture from the 78 | /// kernel driver. 79 | /// 80 | /// Returns `Result::Ok(i)` where `i` is the number of devices (CPUs) detected on the 81 | /// system or `Result::Err(e)` where `e` is the payload with a string containing the detailed 82 | /// error message. 83 | /// 84 | /// # Example 85 | /// 86 | /// ``` 87 | /// let collector = RingBufferCollector::new(); 88 | /// match collector.start() { 89 | /// Ok(num_devs) => { 90 | /// 91 | /// }, 92 | /// Err(e) => { 93 | /// } 94 | /// } 95 | /// ``` 96 | /// 97 | fn start(&mut self) -> Result { 98 | let num_devs = num_cpus::get(); 99 | let len = RING_BUF_SIZE * 2; 100 | 101 | // ~ open and map each of the char devices 102 | // which represent the ring buffers 103 | for i in 0..num_devs { 104 | match open(format!("/dev/sysdig{}", i).as_str(), O_RDWR | O_SYNC, S_IRUSR) { 105 | Ok(fd) => { 106 | let buffer = mmap(ptr::null_mut(), 107 | len, 108 | PROT_READ, 109 | MAP_SHARED, fd, 0); 110 | let buffer_info = mmap(ptr::null_mut(), size_of::(), 111 | PROT_READ | PROT_WRITE, 112 | MAP_SHARED, fd, 0); 113 | if buffer.is_err() || buffer_info.is_err() { 114 | munmap(buffer.unwrap() as *mut libc::c_void, len); 115 | close(fd); 116 | return Err(Error::RingBufferMapping); 117 | } 118 | let dev = RingBufferDev { 119 | fd: fd, 120 | buffer: buffer.unwrap() as *mut libc::c_char, 121 | buffer_info: buffer_info.unwrap() as *mut RingBufferInfo, 122 | last_readsize: 0, 123 | next_syscall: ptr::null_mut(), 124 | len: 0 125 | }; 126 | 127 | self.devs.push(dev); 128 | // ~ send the ioctl code to start the capture 129 | unsafe { ioctl_start(fd); } 130 | 131 | }, 132 | Err(e) => { 133 | match e { 134 | NixError::Sys(err) => { 135 | if err == errno::ENODEV { 136 | continue; 137 | } else if err == errno::EBUSY { 138 | return Err(Error::TooManyCollectors); 139 | } else { 140 | return Err(Error::DeviceError); 141 | } 142 | }, 143 | NixError::InvalidPath => {} 144 | } 145 | } 146 | } 147 | } 148 | Ok(num_devs) 149 | } 150 | 151 | fn stop(&mut self) -> Result<()> { 152 | let len = RING_BUF_SIZE * 2; 153 | for dev in &self.devs { 154 | unsafe { ioctl_stop(dev.fd); } 155 | munmap(dev.buffer as *mut libc::c_void, len); 156 | munmap(dev.buffer_info as *mut libc::c_void, size_of::()); 157 | close(dev.fd); 158 | } 159 | Ok(()) 160 | } 161 | 162 | /// Consumes the next available syscall event from the ring buffer. If the buffers 163 | /// are empty, the head and tail are updated accordingly to pick up the 164 | /// new generated syscall events. When `consecutive_waits` is above the defined threshold, the 165 | /// main thread is suspended for `BUFFER_EMPTY_WAIT_TIME_MS` milliseconds. This can give a 166 | /// chance for buffers to refill. 167 | /// 168 | /// Returns `Some(syscall)` where `syscall` stores a plethora of information about the 169 | /// intercepted syscall event. On error it returns `None`. 170 | /// 171 | /// # Example 172 | /// 173 | /// ``` 174 | /// let collector = RingBufferCollector::new(); 175 | /// loop { 176 | /// match collector.next() { 177 | /// Some(syscall_info) => { 178 | /// println!("syscall name {}", syscall_info.name); 179 | /// }, 180 | /// None => {} 181 | /// } 182 | /// } 183 | /// ``` 184 | /// 185 | fn next(&mut self) -> Option { 186 | let mut cpu = None; 187 | let mut syscall = ptr::null_mut(); 188 | 189 | for (j, dev) in self.devs.iter().enumerate() { 190 | if dev.len == 0 { 191 | continue; 192 | } else { 193 | syscall = dev.next_syscall as *mut Syscall; 194 | cpu = Some(j); 195 | } 196 | } 197 | if cpu != None { 198 | let cpuid = cpu.unwrap(); 199 | unsafe { 200 | assert!(self.devs[cpuid].len >= (*syscall).len); 201 | let len = (*syscall).len as isize; 202 | self.devs[cpuid].len -= (*syscall).len; 203 | self.devs[cpuid].next_syscall = self.devs[cpuid].next_syscall.offset(len); 204 | }; 205 | } else { 206 | // ~ in case buffers are empty 207 | if self.check_next_wait() { 208 | unsafe { libc::usleep(BUFFER_EMPTY_WAIT_TIME_MS * 1000); } 209 | self.consecutive_waits += 1; 210 | } 211 | 212 | for mut dev in &mut self.devs { 213 | let buffer_info = dev.buffer_info; 214 | let ttail: usize = unsafe { ((*buffer_info).tail + dev.last_readsize) as usize }; 215 | if ttail < RING_BUF_SIZE { 216 | unsafe { (*dev.buffer_info).tail = ttail as u32 } 217 | } else { 218 | unsafe { (*dev.buffer_info).tail = (ttail - RING_BUF_SIZE) as u32 } 219 | } 220 | 221 | let read_size = Self::get_buffer_readsize(buffer_info); 222 | dev.last_readsize = read_size; 223 | dev.len = read_size; 224 | 225 | unsafe { dev.next_syscall = dev.buffer.offset(ttail as isize); } 226 | } 227 | } 228 | 229 | if syscall.is_null() { 230 | None 231 | } else { 232 | let id = unsafe { (*syscall).id }; 233 | let ts = unsafe { (*syscall).ts }; 234 | 235 | match self.syscall_table.get_syscall_meta(id as usize) { 236 | Some(meta) => { 237 | let timestamp = NaiveDateTime::from_timestamp((ts / 1000000000) as i64, 0); 238 | let syscall_info = SyscallInfo { 239 | ts: DateTime::::from_utc(timestamp, UTC), 240 | name: meta.name.to_string(), 241 | params: meta.build_params(syscall), 242 | }; 243 | return Some(syscall_info); 244 | 245 | }, 246 | None => { return None; } 247 | } 248 | } 249 | } 250 | } 251 | 252 | impl RingBufferCollector { 253 | 254 | pub fn new() -> RingBufferCollector { 255 | RingBufferCollector { 256 | devs: Vec::::new(), 257 | consecutive_waits: 0, 258 | syscall_table: SyscallTable::default() 259 | } 260 | } 261 | 262 | /// Determines if we should wait while the ring buffers 263 | /// are refilled with new system call events. Returns `true` if the 264 | /// condition is met, or `false` otherwise. 265 | fn check_next_wait(&mut self) -> bool { 266 | let mut res = true; 267 | for dev in &self.devs { 268 | let read_size = Self::get_buffer_readsize(dev.buffer_info); 269 | 270 | if read_size > 20000 { 271 | self.consecutive_waits = 0; 272 | res = false; 273 | } 274 | } 275 | if res == false { 276 | return false 277 | } 278 | 279 | if self.consecutive_waits >= MAX_N_CONSECUTIVE_WAITS { 280 | self.consecutive_waits = 0; 281 | return false; 282 | } else { 283 | return true; 284 | } 285 | } 286 | 287 | /// Calculates the new size of the buffer to be read. 288 | fn get_buffer_readsize(buffer_info: *mut RingBufferInfo) -> u32 { 289 | let head: usize = unsafe { (*buffer_info).head as usize }; 290 | let tail: usize = unsafe { (*buffer_info).tail as usize }; 291 | (if tail > head { RING_BUF_SIZE - tail + head } else { head - tail }) as u32 292 | } 293 | } 294 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | //! Implementation of the TOML based configuration descriptor reader. 2 | use std::fs::File; 3 | use std::io::Read; 4 | use std::path::Path; 5 | use std::env; 6 | use toml; 7 | 8 | use error::{Error, Result}; 9 | 10 | #[derive(Deserialize)] 11 | pub struct KafkaConfig { 12 | pub hosts: Vec, 13 | pub ack_timeout: u64, 14 | pub topic: String 15 | } 16 | 17 | #[derive(Deserialize)] 18 | pub struct Config { 19 | /// kafka broker related configuration 20 | pub kafka: KafkaConfig 21 | } 22 | 23 | /// Reads the configuration descriptor from the TOML file. It first scans the list of well known 24 | /// locations to find a valid configuration file. If non existing path is found, it fallbacks to 25 | /// resolve the configuration file path from `CUBOSTRATUSC_CONFIG` environment variable. 26 | /// 27 | /// If the configuration descriptor can be loaded from any of the available paths and is parsed 28 | /// correctly, this function returns `Result::Ok(config)` where `config` references [Config](struct. 29 | /// Config.html). On error it returns `Result::Err(e)`. 30 | /// 31 | pub fn read_config() -> Result { 32 | let mut content = String::new(); 33 | let locations = vec!["/etc/cubostratusc.toml", "/var/lib/cubostratusc/cubostratusc.toml"]; 34 | let mut path = locations.iter() 35 | .find(|loco| Path::new(*loco).exists()) 36 | .map(|l| l.to_string()); 37 | if path == None { 38 | path = env::var("CUBOSTRATUSC_CONFIG").map(|e| Some(e)).unwrap_or(None); 39 | } 40 | if let Some(path) = path { 41 | File::open(path) 42 | .unwrap() 43 | .read_to_string(&mut content) 44 | .expect("unable to open configuration file"); 45 | toml::from_str(&content).map_err(|e| Error::ConfigParseError(e.to_string())) 46 | } else { 47 | Err(Error::UnknownConfigPathError) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | //! Encapsulates error types. 2 | 3 | use std::result; 4 | use std::fmt; 5 | 6 | pub type Result = result::Result; 7 | 8 | /// Possible errors produced by syscall collector. 9 | #[derive(Deserialize, Debug)] 10 | pub enum Error { 11 | RingBufferMapping, 12 | TooManyCollectors, 13 | DeviceError, 14 | UnknownConfigPathError, 15 | ConfigParseError(String) 16 | } 17 | 18 | impl fmt::Display for Error { 19 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 20 | match *self { 21 | Error::RingBufferMapping => write!(f, "Unable to map ring buffer device"), 22 | Error::TooManyCollectors => write!(f, "Too many collectors attached to device"), 23 | Error::DeviceError => write!(f, "Insufficient privileges to open device \ 24 | or device not loaded"), 25 | Error::UnknownConfigPathError => write!(f, "Unable to resolve \ 26 | configuration file path"), 27 | Error::ConfigParseError(ref e) => write!(f, "Invalid configuration descriptor. \ 28 | Reason: {}", e) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate nix; 3 | extern crate libc; 4 | extern crate num_cpus; 5 | extern crate chrono; 6 | extern crate kafka; 7 | 8 | #[macro_use] 9 | extern crate serde_derive; 10 | extern crate serde_json; 11 | extern crate toml; 12 | #[macro_use] 13 | extern crate nom; 14 | extern crate glob; 15 | 16 | pub mod collector; 17 | pub mod syscall; 18 | pub mod aggregator; 19 | pub mod config; 20 | pub mod state; 21 | mod error; 22 | mod value; 23 | -------------------------------------------------------------------------------- /src/state/cgroups.rs: -------------------------------------------------------------------------------- 1 | //! Parses the proc virtual file system for cgroup (control groups) information. The `/proc/[pid]/cgroup` 2 | //! file describes control groups to which the process belongs. For each cgroup hierarchy there is 3 | //! an entry of the form `hierarchy-id:subsystems:cgroup-path`, for example: 4 | //! 5 | //! 7:cpu,cpuacct:/user.slice 6 | //! 7 | //! where 7 is an unique hierarchy identifier, `cpu` and `cpuacct` are the cgroup subsystems bound 8 | //! to the hierarchy, and finally, `/user.slice` is the cgroup pathname. There is a special `name=systemd` 9 | //! cgroup with no bounded subsystem and is used by `systemd` to track services and user sessions. 10 | 11 | use std::path::PathBuf; 12 | use std::str::{self, FromStr}; 13 | use nom::{alpha, IResult}; 14 | use std::io::{Error, Result, ErrorKind, Read}; 15 | use std::fs::File; 16 | use super::parsers::{consume_until_line_ending, parse_u8}; 17 | 18 | #[derive(Serialize, Debug)] 19 | pub struct CGroup { 20 | /// the unique identifier of the cgroup hierarchy 21 | pub id: u8, 22 | /// vector of cgroup subsystems 23 | pub controllers: Vec, 24 | /// pathname of the control group 25 | pub path: String 26 | } 27 | 28 | // parses cgroup subsystems 29 | named!(controller, recognize!(chain!( 30 | alpha ~ 31 | opt!(alt!(tag!("_") | tag!("="))) ~ 32 | opt!(alpha), 33 | || {}))); 34 | 35 | named!(parse_controllers >, 36 | many0!(do_parse!(c: map_res!( 37 | map_res!( 38 | controller, 39 | str::from_utf8), FromStr::from_str) >> 40 | opt!(tag!(",")) >> 41 | opt!(tag!(":")) >> (c)))); 42 | 43 | 44 | // parses cgroup pathname 45 | named!(parse_path, 46 | map_res!(map_res!(consume_until_line_ending, str::from_utf8), FromStr::from_str)); 47 | 48 | // parses a single entry from the cgroup file 49 | named!(cgroup, do_parse!(id: parse_u8 >> 50 | char!(':') >> 51 | controllers: parse_controllers >> 52 | path: parse_path >> 53 | (CGroup { id: id, 54 | controllers: controllers, 55 | path: path }) 56 | )); 57 | 58 | fn parse_cgroups(buf: &[u8]) -> IResult<&[u8], Vec> { 59 | map!(buf, many0!(cgroup), |c| {c}) 60 | } 61 | 62 | pub fn cgroups(pid: u64, root: String) -> Result> { 63 | let mut buf = String::new(); 64 | let mut f = try!(File::open(format!("{}/{}/cgroup", root, pid))); 65 | f.read_to_string(&mut buf); 66 | match parse_cgroups(buf.as_bytes()) { 67 | IResult::Done(i, o) => { 68 | Ok(o) 69 | }, 70 | IResult::Error(e) => { 71 | Err(Error::new(ErrorKind::InvalidInput, "unable to parse input")) 72 | }, 73 | _ => Err(Error::new(ErrorKind::InvalidInput, "unable to parse input")), 74 | } 75 | } -------------------------------------------------------------------------------- /src/state/fd.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rabbitstack/cubostratus/3a55efbf0cd41931016365605e6f35bbc3f1c6b8/src/state/fd.rs -------------------------------------------------------------------------------- /src/state/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod cgroups; 2 | pub mod thread; 3 | mod parsers; -------------------------------------------------------------------------------- /src/state/net.rs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rabbitstack/cubostratus/3a55efbf0cd41931016365605e6f35bbc3f1c6b8/src/state/net.rs -------------------------------------------------------------------------------- /src/state/parsers.rs: -------------------------------------------------------------------------------- 1 | //! Contains useful [nom](https://github.com/Geal/nom) parsers. 2 | 3 | use std::path::PathBuf; 4 | use nom::not_line_ending; 5 | use std::str::{self, FromStr}; 6 | use std::borrow::ToOwned; 7 | use nom::{digit, alphanumeric}; 8 | 9 | named!(pub consume_until_line_ending, take_until_and_consume!("\n")); 10 | 11 | named!(pub parse_line, 12 | map!(map_res!(not_line_ending, str::from_utf8), ToOwned::to_owned)); 13 | 14 | named!(pub parse_u32_octal, 15 | map_res!(map_res!(alphanumeric, str::from_utf8), 16 | |s| u32::from_str_radix(s, 8))); 17 | 18 | named!(pub parse_u8, 19 | map_res!(map_res!(digit, str::from_utf8), FromStr::from_str)); 20 | 21 | named!(pub parse_u32, 22 | map_res!(map_res!(digit, str::from_utf8), FromStr::from_str)); 23 | 24 | named!(pub parse_u64, 25 | map_res!(map_res!(digit, str::from_utf8), FromStr::from_str)); 26 | -------------------------------------------------------------------------------- /src/state/thread.rs: -------------------------------------------------------------------------------- 1 | //! Parses the `status` files from the `/proc` pseudo file system and collects information about 2 | //! currently running processes. 3 | 4 | use super::parsers::{parse_line, consume_until_line_ending, parse_u32_octal, parse_u64, parse_u32}; 5 | use super::cgroups::{CGroup, cgroups}; 6 | use nom::{IResult, line_ending, space}; 7 | use std::collections::HashMap; 8 | use std::io::{Error, Result, ErrorKind, Read}; 9 | use std::fs::File; 10 | use glob::glob; 11 | use std::path::Path; 12 | 13 | #[derive(Debug, Serialize)] 14 | pub enum ThreadState { 15 | Running, 16 | Sleeping, 17 | Waiting, 18 | Stopped, 19 | TraceStopped, 20 | Dead, 21 | Zombie 22 | } 23 | 24 | pub struct ThreadRegistry { 25 | pub threads: HashMap, 26 | proc_root: String 27 | } 28 | 29 | #[derive(Serialize, Debug)] 30 | pub struct ThreadInfo { 31 | /// filename of the executable 32 | pub comm: String, 33 | /// current state of the process 34 | pub state: ThreadState, 35 | /// process id (i.e., thread group id) 36 | pub pid: u64, 37 | /// thread id 38 | pub tid: u64, 39 | /// process id of the parent process 40 | pub ppid: u64, 41 | /// real user id 42 | pub uid: u32, 43 | /// real group id 44 | pub gid: u32, 45 | /// cgroups bounded to this thread 46 | pub cgroups: Option> 47 | } 48 | 49 | named!(parse_thread_state, 50 | alt!(tag!("R (running)") => { |_| ThreadState::Running } 51 | | tag!("S (sleeping)") => { |_| ThreadState::Sleeping } 52 | | tag!("D (disk sleep)") => { |_| ThreadState::Waiting } 53 | | tag!("T (stopped)") => { |_| ThreadState::Stopped } 54 | | tag!("t (tracing stop)") => { |_| ThreadState::TraceStopped } 55 | | tag!("X (dead)") => { |_| ThreadState::Dead } 56 | | tag!("Z (zombie)") => { |_| ThreadState::Zombie })); 57 | 58 | 59 | named!(parse_command, delimited!(tag!("Name:\t"), parse_line, line_ending)); 60 | named!(parse_umask, delimited!(tag!("Umask:\t"), parse_u32_octal, line_ending)); 61 | named!(parse_state, delimited!(tag!("State:\t"), parse_thread_state, line_ending)); 62 | named!(parse_pid, delimited!(tag!("Tgid:\t"), parse_u64, line_ending)); 63 | named!(parse_tid, delimited!(tag!("Pid:\t"), parse_u64, line_ending)); 64 | named!(parse_ppid, delimited!(tag!("PPid:\t"), parse_u64, line_ending)); 65 | 66 | named!(parse_uid, chain!(tag!("Uid:\t") ~ uid: parse_u32 ~ consume_until_line_ending, 67 | || {(uid)})); 68 | named!(parse_gid, chain!(tag!("Gid:\t") ~ gid: parse_u32 ~ consume_until_line_ending, 69 | || {(gid)})); 70 | 71 | named!(thread_info, 72 | do_parse!( 73 | comm: parse_command >> 74 | opt!(parse_umask) >> 75 | state: parse_state >> 76 | pid: parse_pid >> 77 | consume_until_line_ending >> 78 | tid: parse_tid >> 79 | ppid: parse_ppid >> 80 | consume_until_line_ending >> 81 | uid: parse_uid >> 82 | gid: parse_gid >> 83 | (ThreadInfo { 84 | comm: comm, 85 | state: state, 86 | pid: pid, 87 | tid: tid, 88 | ppid: ppid, 89 | uid: uid, 90 | gid: gid, 91 | cgroups: None, 92 | }) 93 | )); 94 | 95 | fn parse_thread(buf: &[u8]) -> IResult<&[u8], ThreadInfo> { 96 | map!(buf, thread_info, |t| {t}) 97 | } 98 | 99 | pub fn parse_thread_info(pid: u64, root: String) -> Result { 100 | let mut buf = String::new(); 101 | let mut f = try!(File::open(format!("{}/{}/status", root, pid))); 102 | f.read_to_string(&mut buf); 103 | match parse_thread(buf.as_bytes()) { 104 | IResult::Done(i, o) => { 105 | Ok(o) 106 | }, 107 | IResult::Error(e) => { 108 | Err(Error::new(ErrorKind::InvalidInput, "unable to parse status file")) 109 | }, 110 | _ => Err(Error::new(ErrorKind::InvalidInput, "unable to parse status file")), 111 | } 112 | } 113 | 114 | impl ThreadRegistry { 115 | 116 | pub fn new() -> ThreadRegistry { 117 | ThreadRegistry { 118 | threads: HashMap::new(), 119 | proc_root: "/proc".to_string() 120 | } 121 | } 122 | 123 | pub fn collect(&mut self) { 124 | for e in glob(&format!("{}/*[0-9]*", self.proc_root.clone())) 125 | .expect("error") { 126 | match e { 127 | Ok(path) => { 128 | let pid = path.file_name().unwrap() 129 | .to_str() 130 | .unwrap().parse::().unwrap(); 131 | let mut ti = parse_thread_info(pid, self.proc_root.clone()).unwrap(); 132 | ti.cgroups = Some(cgroups(pid, self.proc_root.clone()).unwrap()); 133 | self.threads.insert(pid, ti); 134 | }, 135 | Err(e) => { 136 | 137 | } 138 | } 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/syscall/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod syscall_table; 2 | 3 | use libc; 4 | use std::ffi::CStr; 5 | use std::{ptr, slice}; 6 | use std::mem::size_of; 7 | use std::collections::HashMap; 8 | use chrono::{DateTime, UTC}; 9 | use value::Value; 10 | 11 | #[repr(C, packed)] 12 | pub struct Syscall { 13 | /// timestamp in nanoseconds from epoch 14 | pub ts: u64, 15 | /// the thread id that generated the syscall 16 | pub tid: u64, 17 | /// length of the syscall + header 18 | pub len: u32, 19 | /// the identifier of the syscall 20 | pub id: u16 21 | } 22 | 23 | pub struct SyscallMeta { 24 | /// name of the system call 25 | pub name: &'static str, 26 | /// syscall category 27 | pub category: Category, 28 | /// flags for this syscall 29 | pub flags: Vec, 30 | /// the number of parameters 31 | pub nparams: usize, 32 | /// the list of syscall's parameters 33 | pub params: Vec 34 | } 35 | 36 | pub struct SyscallParam { 37 | /// parameter name 38 | pub name: &'static str, 39 | /// parameter type 40 | pub kind: ParamType, 41 | /// parameter rendering format 42 | pub fmt: ParamFormat 43 | } 44 | 45 | #[derive(Serialize, Debug)] 46 | pub struct SyscallInfo { 47 | /// timestamp expressed as UTC date/time structure 48 | pub ts: DateTime, 49 | /// name of the system call 50 | pub name: String, 51 | /// syscall's parameter map 52 | pub params: HashMap 53 | 54 | } 55 | 56 | /// determines the syscall category 57 | pub enum Category { 58 | Unknown, 59 | Other, 60 | File, 61 | Net, 62 | IPC, 63 | Memory, 64 | Process, 65 | Sleep, 66 | System, 67 | Signal, 68 | User, 69 | Time, 70 | Processing, 71 | IOBase, 72 | IORead, 73 | IOWrite, 74 | IOOther, 75 | Wait, 76 | Scheduler, 77 | Internal 78 | 79 | } 80 | 81 | pub enum Flags { 82 | None, 83 | CreatesFd, 84 | DestroysFd, 85 | UsesFd, 86 | ReadsFromFd, 87 | WritesToFd, 88 | ModifiesState, 89 | Unused, 90 | Waits, 91 | SkipParser, 92 | OldVesion 93 | 94 | } 95 | 96 | pub enum ParamType { 97 | None, 98 | Int8, 99 | Int16, 100 | Int32, 101 | Int64, 102 | UInt8, 103 | UInt16, 104 | UInt32, 105 | UInt64, 106 | /// a NULL terminated printable buffer of bytes 107 | CharBuffer, 108 | ByteBuffer, 109 | ErrNo, 110 | SockAddr, 111 | SockTuple, 112 | Fd, 113 | Pid, 114 | FdList, 115 | FsPath, 116 | SyscallId, 117 | SigType, 118 | /// a relative time 119 | RelTime, 120 | /// an absolute time interval 121 | AbsTime, 122 | Port, 123 | L4Proto, 124 | SockFamily, 125 | Bool, 126 | Ipv4Addr, 127 | Dyn, 128 | Flags8, 129 | Flags16, 130 | Flags32, 131 | Uid, 132 | Gid, 133 | Double, 134 | Sigset, 135 | CharBufferArray, 136 | CharBufferPairArray, 137 | Ipv4Net 138 | } 139 | 140 | pub enum ParamFormat { 141 | Na, 142 | Dec, 143 | Hex, 144 | PaddedDec, 145 | Id, 146 | Dir 147 | } 148 | 149 | pub enum Direction { 150 | Enter, 151 | Exit 152 | } 153 | 154 | impl SyscallMeta { 155 | /// Populates the syscall parameter map by applying pointer arithmetic 156 | /// operations on the system call structure. The parameter's buffer is extracted 157 | /// from the slice which is constructed from syscall structure pointer 158 | /// and the number of parameters. 159 | /// For each parameter found in the slice, the parsing stage is delegated to 160 | /// the `SyscallParam::parse` method. The return value of the previous method is put into 161 | /// the hash map and indexed by parameter name. 162 | /// 163 | pub fn build_params(&self, syscall: *mut Syscall) -> HashMap { 164 | let mut params = HashMap::::default(); 165 | unsafe { 166 | let lens = syscall.offset(1) as *const u16; 167 | let mut buf = lens.offset(self.nparams as isize) as *const u8; 168 | for (i, len) in slice::from_raw_parts(lens, self.nparams) 169 | .iter() 170 | .enumerate() { 171 | let ref param = self.params[i]; 172 | params.insert(param.name.to_string(), param.parse(buf)); 173 | buf = buf.offset(*len as isize); 174 | } 175 | } 176 | params 177 | } 178 | } 179 | 180 | impl SyscallParam { 181 | /// Transforms the raw buffer which contains the parameter value to a native 182 | /// data type suitable for serialization. 183 | pub fn parse(&self, buf: *const u8) -> Value { 184 | match self.kind { 185 | ParamType::Int8 => { 186 | unsafe { Value::Int8(*(buf as *const i8)) } 187 | }, 188 | ParamType::Int16 => { 189 | unsafe { Value::Int16(*(buf as *const i16)) } 190 | }, 191 | ParamType::Int32 => { 192 | unsafe { Value::Int32(*(buf as *const i32)) } 193 | }, 194 | ParamType::Int64 => { 195 | unsafe { Value::Int64(*(buf as *const i64)) } 196 | }, 197 | ParamType::UInt8 => { 198 | unsafe { Value::UInt8(*(buf as *const u8)) } 199 | }, 200 | ParamType::UInt16 => { 201 | unsafe { Value::UInt16(*(buf as *const u16)) } 202 | }, 203 | ParamType::UInt32 => { 204 | unsafe { Value::UInt32(*(buf as *const u32)) } 205 | }, 206 | ParamType::UInt64 => { 207 | unsafe { Value::UInt64(*(buf as *const u64)) } 208 | }, 209 | ParamType::FsPath => { 210 | Value::String(self.to_string(buf)) 211 | }, 212 | ParamType::ErrNo => { 213 | unsafe { Value::Int64(*(buf as *const i64)) } 214 | }, 215 | ParamType::Fd => { 216 | unsafe { Value::Int64(*(buf as *const i64)) } 217 | }, 218 | ParamType::Pid => { 219 | unsafe { Value::Int64(*(buf as *const i64)) } 220 | }, 221 | ParamType::Uid | ParamType::Gid => { 222 | unsafe { Value::UInt32(*(buf as *const u32)) } 223 | }, 224 | ParamType::SyscallId => { 225 | unsafe { Value::UInt16(*(buf as *const u16)) } 226 | }, 227 | ParamType::CharBuffer => { 228 | Value::String(self.to_string(buf)) 229 | }, 230 | ParamType::ByteBuffer => { 231 | Value::String(self.to_string(buf)) 232 | } 233 | _ => Value::None 234 | } 235 | } 236 | 237 | fn to_string(&self, buf: *const u8) -> String { 238 | unsafe { 239 | CStr::from_ptr(buf as *const libc::c_char).to_string_lossy().into_owned() 240 | } 241 | } 242 | } -------------------------------------------------------------------------------- /src/syscall/syscall_table.rs: -------------------------------------------------------------------------------- 1 | use super::{SyscallMeta, SyscallParam, Category, Flags, ParamType, ParamFormat}; 2 | 3 | pub enum Syscalls { 4 | GenericEnter = 0, 5 | GenericExit = 1, 6 | OpenEnter = 2, 7 | OpenExit = 3, 8 | CloseEnter = 4, 9 | CloseExit = 5, 10 | ReadEnter = 6, 11 | ReadExit = 7, 12 | WriteEnter = 8, 13 | WriteExit = 9, 14 | Brk1Enter = 10, 15 | Brk1Exit = 11, 16 | Execve8Enter = 12, 17 | Execve8Exit = 13, 18 | Clone11Enter = 14, 19 | Clone11Exit = 15, 20 | ProcExitEnter = 16, 21 | ProcExitExit = 17, 22 | SocketEnter = 18, 23 | SocketExit = 19, 24 | BindEnter = 20, 25 | BindExit = 21, 26 | ConnectEnter = 22, 27 | ConnectExit = 23, 28 | ListenEnter = 24, 29 | ListenExit = 25, 30 | AcceptEnter = 26, 31 | AcceptExit = 27, 32 | SendEnter = 28, 33 | SendExit = 29, 34 | SendToEnter = 30, 35 | SendToExit = 31, 36 | RecvEnter = 32, 37 | RecvExit = 33, 38 | RecvFromEnter = 34, 39 | RecvFromExit = 35, 40 | ShutdownEnter = 36, 41 | ShutdownExit = 37, 42 | GetSockNameEnter = 38, 43 | GetSockNameExit = 39, 44 | GetPeerNameEnter = 40, 45 | GetPeerNameExit = 41, 46 | SocketPairEnter = 42, 47 | SocketPairExit = 43, 48 | SetSockOptEnter = 44, 49 | SetSockOptExit = 45, 50 | GetSockOptEnter = 46, 51 | GetSockOptExit = 47, 52 | SendMsgEnter = 48, 53 | SendMsgExit = 49, 54 | SendMMsgEnter = 50, 55 | SendMMsgExit = 51, 56 | RecvMsgEnter = 52, 57 | RecvMsgExit = 53, 58 | RecvMMsgEnter = 54, 59 | RecvMMsgExit = 55, 60 | Accept4Enter = 56, 61 | Accept4Exit = 57, 62 | CreatEnter = 58, 63 | CreatExit = 59, 64 | PipeEnter = 60, 65 | PipeExit = 61, 66 | EventFdEnter = 62, 67 | EventFdExit = 63, 68 | FutexEnter = 64, 69 | FutexExit = 65, 70 | StatEnter = 66, 71 | StatExit = 67, 72 | LstatEnter = 68, 73 | LstatExit = 69, 74 | FstatEnter = 70, 75 | FstatExit = 71, 76 | Stat64Enter = 72, 77 | Stat64Exit = 73, 78 | Lstat64Enter = 74, 79 | Lstat64Exit = 75, 80 | Fstat64Enter = 76, 81 | Fstat64Exit = 77, 82 | EpollWaitEnter = 78, 83 | EpollWaitExit = 79, 84 | PollEnter = 80, 85 | PollExit = 81, 86 | SelectEnter = 82, 87 | SelectExit = 83, 88 | NewSelectEnter = 84, 89 | NewSelectExit = 85, 90 | 91 | } 92 | 93 | pub struct SyscallTable { 94 | syscall_metas: Vec 95 | } 96 | 97 | impl Default for SyscallTable { 98 | 99 | fn default() -> SyscallTable { 100 | SyscallTable { 101 | syscall_metas: vec![ 102 | SyscallMeta{ name: "syscall", category: Category::Other, flags: vec![Flags::None], nparams: 2, params: vec![SyscallParam { name: "id", kind: ParamType::SyscallId, fmt: ParamFormat::Dec }, SyscallParam { name: "native_id", kind: ParamType::UInt16, fmt: ParamFormat::Dec } ] }, 103 | SyscallMeta{ name: "syscall", category: Category::Other, flags: vec![Flags::None], nparams: 1, params: vec![SyscallParam { name: "id", kind: ParamType::SyscallId, fmt: ParamFormat::Dec }]}, 104 | SyscallMeta{ name: "open", category: Category::File, flags: vec![Flags::CreatesFd, Flags::ModifiesState], nparams: 0, params: vec![]}, 105 | SyscallMeta{ name: "open", category: Category::File, flags: vec![Flags::CreatesFd, Flags::ModifiesState], nparams: 4, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec}, SyscallParam {name: "name", kind: ParamType::FsPath, fmt: ParamFormat::Na}, SyscallParam { name: "flags", kind: ParamType::Flags32, fmt: ParamFormat::Hex}, SyscallParam {name: "mode", kind: ParamType::UInt32, fmt: ParamFormat::Hex} ] }, 106 | SyscallMeta{ name: "close", category: Category::IOOther, flags: vec![Flags::DestroysFd, Flags::UsesFd, Flags::ModifiesState], nparams: 1, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }]}, 107 | SyscallMeta{ name: "close", category: Category::IOOther, flags: vec![Flags::DestroysFd, Flags::UsesFd, Flags::ModifiesState], nparams: 1, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }]}, 108 | SyscallMeta{ name: "read", category: Category::IORead, flags: vec![Flags::UsesFd, Flags::ReadsFromFd], nparams: 2, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam{ name: "size", kind: ParamType::UInt32, fmt: ParamFormat::Dec }]}, 109 | SyscallMeta{ name: "read", category: Category::IORead, flags: vec![Flags::UsesFd, Flags::ReadsFromFd], nparams: 2, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam{ name: "data", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }]}, 110 | SyscallMeta{ name: "write", category: Category::IOWrite, flags: vec![Flags::UsesFd, Flags::WritesToFd], nparams: 2, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam{ name: "size", kind: ParamType::UInt32, fmt: ParamFormat::Dec }]}, 111 | SyscallMeta{ name: "write", category: Category::IOWrite, flags: vec![Flags::UsesFd, Flags::WritesToFd], nparams: 2, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam{ name: "data", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }]}, 112 | SyscallMeta{ name: "brk", category: Category::Memory, flags: vec![Flags::OldVesion], nparams: 1, params: vec![SyscallParam { name: "size", kind: ParamType::UInt32, fmt: ParamFormat::Dec }]}, 113 | SyscallMeta{ name: "brk", category: Category::Memory, flags: vec![Flags::OldVesion], nparams: 1, params: vec![SyscallParam { name: "res", kind: ParamType::UInt64, fmt: ParamFormat::Hex }]}, 114 | SyscallMeta{ name: "execve", category: Category::Process, flags: vec![Flags::ModifiesState], nparams: 0, params: vec![]}, 115 | SyscallMeta{ name: "execve", category: Category::Process, flags: vec![Flags::ModifiesState, Flags::OldVesion], nparams: 8, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam { name: "exe", kind: ParamType::CharBuffer, fmt: ParamFormat::Na }, SyscallParam { name: "args", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }, SyscallParam { name: "tid", kind: ParamType::Pid, fmt: ParamFormat::Dec }, SyscallParam { name: "pid", kind: ParamType::Pid, fmt: ParamFormat::Dec }, SyscallParam { name: "ptid", kind: ParamType::Pid, fmt: ParamFormat::Dec }, SyscallParam { name: "cwd", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }, SyscallParam { name: "fdlimit", kind: ParamType::UInt64, fmt: ParamFormat::Dec }]}, 116 | SyscallMeta{ name: "clone", category: Category::Process, flags: vec![Flags::ModifiesState], nparams: 0, params: vec![]}, 117 | SyscallMeta{ name: "clone", category: Category::Process, flags: vec![Flags::ModifiesState], nparams: 11, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam{ name: "exe", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }, SyscallParam{ name: "args", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }, SyscallParam { name: "tid", kind: ParamType::Pid, fmt: ParamFormat::Dec }, SyscallParam { name: "pid", kind: ParamType::Pid, fmt: ParamFormat::Dec }, SyscallParam { name: "ptid", kind: ParamType::Pid, fmt: ParamFormat::Dec }, SyscallParam { name: "cwd", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }, SyscallParam { name: "fdlimit", kind: ParamType::UInt64, fmt: ParamFormat::Dec }, SyscallParam { name: "flags", kind: ParamType::Flags32, fmt: ParamFormat::Hex }, SyscallParam { name: "uid", kind: ParamType::UInt32, fmt: ParamFormat::Dec }, SyscallParam { name: "gid", kind: ParamType::UInt32, fmt: ParamFormat::Dec } ]}, 118 | SyscallMeta{ name: "procexit", category: Category::Process, flags: vec![Flags::ModifiesState], nparams: 0, params: vec![]}, 119 | SyscallMeta{ name: "procexit", category: Category::Process, flags: vec![Flags::Unused], nparams: 0, params: vec![]}, 120 | SyscallMeta{ name: "socket", category: Category::Net, flags: vec![Flags::CreatesFd, Flags::ModifiesState], nparams: 2, params: vec![SyscallParam { name: "domain", kind: ParamType::Flags32, fmt: ParamFormat::Dec }, SyscallParam{ name: "proto", kind: ParamType::UInt32, fmt: ParamFormat::Dec }]}, 121 | SyscallMeta{ name: "socket", category: Category::Net, flags: vec![Flags::CreatesFd, Flags::ModifiesState], nparams: 1, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }]}, 122 | SyscallMeta{ name: "bind", category: Category::Net, flags: vec![Flags::UsesFd, Flags::ModifiesState], nparams: 1, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }]}, 123 | SyscallMeta{ name: "bind", category: Category::Net, flags: vec![Flags::UsesFd, Flags::ModifiesState], nparams: 2, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam { name: "addr", kind: ParamType::SockAddr, fmt: ParamFormat::Na }]}, 124 | SyscallMeta{ name: "connect", category: Category::Net, flags: vec![Flags::UsesFd, Flags::ModifiesState], nparams: 1, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }]}, 125 | SyscallMeta{ name: "connect", category: Category::Net, flags: vec![Flags::UsesFd, Flags::ModifiesState], nparams: 2, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam { name: "tuple", kind: ParamType::SockAddr, fmt: ParamFormat::Na }]}, 126 | SyscallMeta{ name: "listen", category: Category::Net, flags: vec![Flags::UsesFd], nparams: 2, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "backlog", kind: ParamType::UInt32, fmt: ParamFormat::Dec }]}, 127 | SyscallMeta{ name: "listen", category: Category::Net, flags: vec![Flags::UsesFd], nparams: 1, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }]}, 128 | SyscallMeta{ name: "accept", category: Category::Net, flags: vec![Flags::CreatesFd, Flags::ModifiesState], nparams: 0, params: vec![]}, 129 | SyscallMeta{ name: "accept", category: Category::Net, flags: vec![Flags::CreatesFd, Flags::ModifiesState], nparams: 3, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "tuple", kind: ParamType::SockTuple, fmt: ParamFormat::Na }, SyscallParam { name: "queuepct", kind: ParamType::UInt8, fmt: ParamFormat::Dec }]}, 130 | SyscallMeta{ name: "send", category: Category::IOWrite, flags: vec![Flags::UsesFd, Flags::WritesToFd], nparams: 2, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "size", kind: ParamType::UInt32, fmt: ParamFormat::Dec }]}, 131 | SyscallMeta{ name: "send", category: Category::IOWrite, flags: vec![Flags::UsesFd, Flags::WritesToFd], nparams: 2, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Na }, SyscallParam { name: "data", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }]}, 132 | SyscallMeta{ name: "sendto", category: Category::IOWrite, flags: vec![Flags::UsesFd, Flags::WritesToFd, Flags::ModifiesState], nparams: 3, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "size", kind: ParamType::UInt32, fmt: ParamFormat::Dec }, SyscallParam { name: "tuple", kind: ParamType::SockTuple, fmt: ParamFormat::Na }]}, 133 | SyscallMeta{ name: "sendto", category: Category::IOWrite, flags: vec![Flags::UsesFd, Flags::WritesToFd, Flags::ModifiesState], nparams: 2, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Na }, SyscallParam { name: "data", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }]}, 134 | SyscallMeta{ name: "recv", category: Category::IORead, flags: vec![Flags::UsesFd, Flags::ReadsFromFd], nparams: 2, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "size", kind: ParamType::UInt32, fmt: ParamFormat::Dec }]}, 135 | SyscallMeta{ name: "recv", category: Category::IORead, flags: vec![Flags::UsesFd, Flags::ReadsFromFd], nparams: 2, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam { name: "data", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }]}, 136 | SyscallMeta{ name: "recvfrom", category: Category::IORead, flags: vec![Flags::UsesFd, Flags::ReadsFromFd, Flags::ModifiesState], nparams: 2, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "size", kind: ParamType::UInt32, fmt: ParamFormat::Dec }]}, 137 | SyscallMeta{ name: "recvfrom", category: Category::IORead, flags: vec![Flags::UsesFd, Flags::ReadsFromFd, Flags::ModifiesState], nparams: 3, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam { name: "data", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }, SyscallParam { name: "tuple", kind: ParamType::SockTuple, fmt: ParamFormat::Na }]}, 138 | SyscallMeta{ name: "shutdown", category: Category::Net, flags: vec![Flags::UsesFd, Flags::ModifiesState], nparams: 2, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "how", kind: ParamType::Flags8, fmt: ParamFormat::Hex }]}, 139 | SyscallMeta{ name: "shutdown", category: Category::Net, flags: vec![Flags::UsesFd, Flags::ModifiesState], nparams: 1, params: vec![SyscallParam { name: "fd", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }]}, 140 | SyscallMeta{ name: "getsockname", category: Category::Net, flags: vec![Flags::None], nparams: 0, params: vec![] }, 141 | SyscallMeta{ name: "getsockname", category: Category::Net, flags: vec![Flags::None], nparams: 0, params: vec![] }, 142 | SyscallMeta{ name: "getpeername", category: Category::Net, flags: vec![Flags::None], nparams: 0, params: vec![] }, 143 | SyscallMeta{ name: "getpeername", category: Category::Net, flags: vec![Flags::None], nparams: 0, params: vec![] }, 144 | SyscallMeta{ name: "socketpair", category: Category::IPC, flags: vec![Flags::CreatesFd, Flags::ModifiesState], nparams: 3, params: vec![SyscallParam { name: "domain", kind: ParamType::Flags32, fmt: ParamFormat::Dec }, SyscallParam { name: "type", kind: ParamType::UInt32, fmt: ParamFormat::Dec }, SyscallParam { name: "proto", kind: ParamType::UInt32, fmt: ParamFormat::Dec }]}, 145 | SyscallMeta{ name: "socketpair", category: Category::IPC, flags: vec![Flags::CreatesFd, Flags::ModifiesState], nparams: 4, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam { name: "fd1", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "fd2", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "peer", kind: ParamType::UInt64, fmt: ParamFormat::Hex }]}, 146 | SyscallMeta{ name: "setsockopt", category: Category::Net, flags: vec![Flags::None], nparams: 0, params: vec![] }, 147 | SyscallMeta{ name: "setsockopt", category: Category::Net, flags: vec![Flags::None], nparams: 0, params: vec![] }, 148 | SyscallMeta{ name: "getsockopt", category: Category::Net, flags: vec![Flags::None], nparams: 0, params: vec![] }, 149 | SyscallMeta{ name: "getsockopt", category: Category::Net, flags: vec![Flags::None], nparams: 0, params: vec![] }, 150 | SyscallMeta{ name: "sendmsg", category: Category::IOWrite, flags: vec![Flags::UsesFd, Flags::ModifiesState, Flags::WritesToFd], nparams: 3, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }, SyscallParam { name: "size", kind: ParamType::UInt32, fmt: ParamFormat::Dec }, SyscallParam { name: "tuple", kind: ParamType::SockTuple, fmt: ParamFormat::Na }]}, 151 | SyscallMeta{ name: "sendmsg", category: Category::IOWrite, flags: vec![Flags::UsesFd, Flags::ModifiesState, Flags::WritesToFd], nparams: 2, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam { name: "data", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }]}, 152 | SyscallMeta{ name: "sendmmsg", category: Category::IOWrite, flags: vec![], nparams: 0, params: vec![] }, 153 | SyscallMeta{ name: "sendmmsg", category: Category::IOWrite, flags: vec![], nparams: 0, params: vec![] }, 154 | SyscallMeta{ name: "recvmsg", category: Category::IORead, flags: vec![Flags::UsesFd, Flags::ModifiesState, Flags::ReadsFromFd], nparams: 1, params: vec![SyscallParam { name: "fd", kind: ParamType::Fd, fmt: ParamFormat::Dec }]}, 155 | SyscallMeta{ name: "recvmsg", category: Category::IORead, flags: vec![Flags::UsesFd, Flags::ModifiesState, Flags::ReadsFromFd], nparams: 4, params: vec![SyscallParam { name: "res", kind: ParamType::ErrNo, fmt: ParamFormat::Dec }, SyscallParam { name: "size", kind: ParamType::UInt32, fmt: ParamFormat::Dec }, SyscallParam { name: "data", kind: ParamType::ByteBuffer, fmt: ParamFormat::Na }, SyscallParam { name: "tuple", kind: ParamType::SockTuple, fmt: ParamFormat::Na }]}, 156 | SyscallMeta{ name: "recvmmsg", category: Category::IORead, flags: vec![], nparams: 0, params: vec![] }, 157 | SyscallMeta{ name: "recvmmsg", category: Category::IORead, flags: vec![], nparams: 0, params: vec![] }, 158 | SyscallMeta{ name: "accept", category: Category::Net, flags: vec![Flags::ModifiesState, Flags::CreatesFd], nparams: 1, params: vec![SyscallParam { name: "flags", kind: ParamType::Int32, fmt: ParamFormat::Hex }]}, 159 | 160 | 161 | 162 | 163 | 164 | ] 165 | 166 | } 167 | } 168 | } 169 | 170 | impl SyscallTable { 171 | pub fn get_syscall_meta(&self, id: usize) -> Option<&SyscallMeta> { 172 | self.syscall_metas.get(id) 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/value.rs: -------------------------------------------------------------------------------- 1 | /// Container for primitive stack allocated `(i32, u32, bool, etc)` as well as heap 2 | /// allocated `(String)` data types. This enum is used by `SyscallParam::parse` method 3 | /// to store the content of the system call parameter's payload. 4 | /// Some syscall's parameters can have multiple attributes, for example, the socket tuple 5 | /// is comprised of IP address and port number. In that case, the `Value` enum can also have 6 | /// structures associated with it. 7 | #[derive(Serialize, Debug)] 8 | #[serde(untagged)] 9 | pub enum Value { 10 | String(String), 11 | Int8(i8), 12 | Int16(i16), 13 | Int32(i32), 14 | Int64(i64), 15 | UInt8(u8), 16 | UInt16(u16), 17 | UInt32(u32), 18 | UInt64(u64), 19 | None 20 | } 21 | --------------------------------------------------------------------------------