Prechádzať zdrojové kódy

examples/uptime.rs: add `uptime` example (no packet data, but helper use)

Quentin Monnet 8 rokov pred
rodič
commit
992f98a55c
1 zmenil súbory, kde vykonal 67 pridanie a 0 odobranie
  1. 67 0
      examples/uptime.rs

+ 67 - 0
examples/uptime.rs

@@ -0,0 +1,67 @@
+// Copyright 2016 6WIND S.A. <quentin.monnet@6wind.com>
+//
+// Licensed under the Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0> or
+// the MIT license <http://opensource.org/licenses/MIT>, at your option. This file may not be
+// copied, modified, or distributed except according to those terms.
+
+
+extern crate rbpf;
+use rbpf::helpers;
+
+// The main objectives of this example is to show:
+//
+// * the use of EbpfVmNoData function,
+// * and the use of a helper.
+//
+// The two eBPF programs are independent and are not related to one another.
+fn main() {
+    let prog1 = vec![
+        0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov32 r0, 0
+        0xb4, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // mov32 r1, 2
+        0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // add32 r0, 1
+        0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // add32 r0, r1
+        0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // exit and return r0
+    ];
+
+    // We use helper `bpf_time_getns()`, which is similar to helper `bpf_ktime_getns()` from Linux
+    // kernel. Hence rbpf::helpers module provides the index of this in-kernel helper as a
+    // constant, so that we can remain compatible with programs for the kernel. Here we also cast
+    // it to a u8 so as to use it directly in program instructions.
+    let hkey = helpers::BPF_KTIME_GETNS_IDX as u8;
+    let prog2 = vec![
+        0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
+        0xb7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
+        0xb7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
+        0xb7, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
+        0xb7, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
+        0x85, 0x00, 0x00, 0x00, hkey, 0x00, 0x00, 0x00, // call helper <hkey>
+        0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // exit and return r0
+    ];
+
+    // Create a VM: this one takes no data. Load prog1 in it.
+    let mut vm = rbpf::EbpfVmNoData::new(&prog1);
+    // Execute prog1.
+    assert_eq!(vm.prog_exec(), 0x3);
+
+    // As struct EbpfVmNoData does not takes any memory area, its return value is mostly
+    // deterministic. So we know prog1 will always return 3. There is an exception: when it uses
+    // helpers, the latter may have non-deterministic values, and all calls may not return the same
+    // value.
+    //
+    // In the following example we use a helper to get the elapsed time since boot time: we
+    // reimplement uptime in eBPF, in Rust. Because why not.
+
+    vm.set_prog(&prog2);
+    vm.register_helper(helpers::BPF_KTIME_GETNS_IDX, helpers::bpf_time_getns);
+
+    vm.jit_compile();
+    let t = unsafe { vm.prog_exec_jit() };
+
+    let d =  t / 10u64.pow(9)  / 60   / 60  / 24;
+    let h = (t / 10u64.pow(9)  / 60   / 60) % 24;
+    let m = (t / 10u64.pow(9)  / 60 ) % 60;
+    let s = (t / 10u64.pow(9)) % 60;
+    let ns = t % 10u64.pow(9);
+
+    println!("Uptime: {:#x} ns == {} days {:02}:{:02}:{:02}, {} ns", t, d, h, m, s, ns);
+}