Basic listing of the network devices.
[virt-mem.git] / lib / virt_mem_net_devices.ml
index a7078af..8ce8eb3 100644 (file)
@@ -37,8 +37,6 @@ supported Linux distribution, see this page about adding support:
       image.domname kernel_version;
     image, None
   ) else (
-    let size = net_device_size kernel_version in
-
     (* In kernels < ~ 2.6.22, this is a simple linked list:
      *   dev_base -> next -> next
      * In kernels >= 2.6.23, this is a list_head:
@@ -50,10 +48,10 @@ supported Linux distribution, see this page about adding support:
       if available then
        Some map_next
       else (
-       let { field_available = available; field_offset = offset } =
+       let { field_available = available } =
          field_signature_of_net_device_dev_list'next kernel_version in
        if available then
-         Some (map_dev_list offset)
+         Some map_dev_list
        else (
          eprintf (f_"%s: kernel net_device table is not linked through either next pointer or dev_list list_head.  Cannot read net devices.\n") image.domname;
          None
@@ -66,7 +64,7 @@ supported Linux distribution, see this page about adding support:
     | Some map ->
        (* What is the starting point for iteration?  In older kernels
         * it was the symbol 'dev_base'.  Then briefly (2.6.22-2.6.24)
-        * it became 'sruct list_head dev_base_head'.  Then when net
+        * it became 'struct list_head dev_base_head'.  Then when net
         * namespaces were introduced (>= 2.6.25) it became 'struct
         * list_head init_net.dev_base_head'.
         *)
@@ -75,7 +73,6 @@ supported Linux distribution, see this page about adding support:
          with Not_found ->
            try
              let addr = Ksymmap.find "dev_base_head" ksymmap in
-             let addr = Virt_mem_mmap.follow_pointer image.mem addr in
              Some addr
            with Not_found ->
              try
@@ -84,8 +81,9 @@ supported Linux distribution, see this page about adding support:
                  eprintf (f_"%s: struct net not available in this kernel version.\n") image.domname;
                  raise Not_found
                );
-               let init_net = get_net kernel_version image.mem addr in
-               let addr = init_net.net_dev_base_head'next in
+               let { field_offset = offset } =
+                 field_signature_of_net_dev_base_head'next kernel_version in
+               let addr = addr +^ Int64.of_int offset in
                Some addr
              with Not_found ->
                eprintf (f_"%s: cannot find dev_base, dev_base_head or init_net symbols in kernel image.\n") image.domname;
@@ -97,7 +95,7 @@ supported Linux distribution, see this page about adding support:
        | Some addr ->
            (* Map over the structure using previously defined map function. *)
            let image, netdevs =
-             map image kernel_version addr size (
+             map kernel_version image addr (
                fun netdev ->
                  { netdev_name = truncate_c_string netdev.net_device_name;
                    netdev_dev_addr = netdev.net_device_dev_addr }
@@ -107,40 +105,31 @@ supported Linux distribution, see this page about adding support:
   )
 
 (* Map dev_base_head -> list_head dev_list -> ... *)
-and map_dev_list offset image kernel_version first_addr size f =
-  eprintf "map_dev_list: first_addr is %Lx\n" first_addr;
+and map_dev_list kernel_version image lh_addr f =
+  let { field_offset = offset } =
+    field_signature_of_net_device_dev_list'next kernel_version in
+  let lh = Virt_mem_list_head.create image lh_addr offset in
 
-  (* The list_head points into the middle of the structure.
-   * Adjust this address to point to the start of the
-   * structure.
-   *)
-  let addr = Int64.sub first_addr (Int64.of_int offset) in
-  eprintf "map_dev_list: after subtracting, addr is %Lx\n" addr;
+  let size = net_device_size kernel_version in
+  let image, lh = Virt_mem_list_head.load_all lh size in
 
-  let rec loop i image acc addr =
-    if i <= max_net_devices then (
-      eprintf "map_dev_list: called at %Lx\n" addr;
-      let mapped = Virt_mem_mmap.is_mapped_range image.mem addr size in
-      let image =
-       if not mapped then
-         Virt_mem_types.load_memory image addr size
-       else
-         image in
-      let dev = get_net_device kernel_version image.mem addr in
-      eprintf "map_dev_list: %Lx %S\n" addr dev.net_device_name;
-      let acc = f dev :: acc in
-      let addr = Option.get dev.net_device_dev_list'next in
-      if addr <> first_addr then
-       loop (i+1) image acc addr
-      else
-       image, acc
-    ) else
-      failwith (sprintf (f_"%s: too many network devices") image.domname);
-  in
-  loop 0 image [] addr
+  let net_devices, _ =
+    Virt_mem_list_head.fold lh ([], 0) (
+      fun (net_devices, i) addr ->
+       if i > max_net_devices then
+         failwith (sprintf (f_"%s: too many network devices") image.domname);
+
+       let net_device = get_net_device kernel_version image.mem addr in
+       let net_devices = f net_device :: net_devices in
+       (net_devices, i+1)
+    ) in
+
+  image, net_devices
 
 (* Iterate dev_base -> next -> next ... *)
-and map_next image kernel_version addr size f =
+and map_next kernel_version image addr f =
+  let size = net_device_size kernel_version in
+
   let rec loop i image acc addr =
     if i <= max_net_devices then (
       if addr <> 0L then (
@@ -151,7 +140,6 @@ and map_next image kernel_version addr size f =
          else
            image in
        let dev = get_net_device kernel_version image.mem addr in
-       eprintf "map_next: %S\n" dev.net_device_name;
        let acc = f dev :: acc in
        let addr =
          match dev.net_device_next with