virt_mem_mmap.cmo: virt_mem_utils.cmo virt_mem_mmap.cmi
virt_mem_mmap.cmx: virt_mem_utils.cmx virt_mem_mmap.cmi
virt_mem_net_devices.cmo: virt_mem_utils.cmo virt_mem_types.cmi \
- virt_mem_mmap.cmi virt_mem_gettext.cmo kernel_net_device.cmi \
- kernel_net.cmi virt_mem_net_devices.cmi
+ virt_mem_mmap.cmi virt_mem_list_head.cmi virt_mem_gettext.cmo \
+ kernel_net_device.cmi kernel_net.cmi virt_mem_net_devices.cmi
virt_mem_net_devices.cmx: virt_mem_utils.cmx virt_mem_types.cmx \
- virt_mem_mmap.cmx virt_mem_gettext.cmx kernel_net_device.cmx \
- kernel_net.cmx virt_mem_net_devices.cmi
+ virt_mem_mmap.cmx virt_mem_list_head.cmx virt_mem_gettext.cmx \
+ kernel_net_device.cmx kernel_net.cmx virt_mem_net_devices.cmi
virt_mem_tasks.cmo: virt_mem_utils.cmo virt_mem_types.cmi \
virt_mem_list_head.cmi virt_mem_gettext.cmo kernel_task_struct.cmi \
virt_mem_tasks.cmi
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:
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
| 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'.
*)
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
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;
| 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 }
)
(* 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 (
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