virt-ifconfig working again
[virt-mem.git] / ifconfig / virt_ifconfig.ml
index b423fe3..1d73bc0 100644 (file)
@@ -23,21 +23,107 @@ open Virt_mem_gettext.Gettext
 open Virt_mem_utils
 open Virt_mem_types
 
-(*
-open Kernel_task_struct
+open Kernel
 
-let run debug { domname = domname; mem = mem } { net_devices = net_devices } =
-  let net_devices = Option.get net_devices in
+let run debug { addrmap = addrmap } =
+  (* Get all net_devices.  When people really start to use network
+   * namespaces, we'll need to divide these by namespace (ie. using
+   * struct net). XXX
+   *)
+  let net_devices = AddrMap.fold (
+    fun _ v devs ->
+      match v with
+      | _, Some (_, _, Net_device dev) -> dev :: devs
+      | _ -> devs
+  ) addrmap [] in
 
-  (* Sort by device name. *)
-  let cmp { netdev_name = n1 } { netdev_name = n2 } = compare n1 n2 in
+  let net_devices = List.map (
+    fun ({ net_device_name = name } as dev) ->
+      { dev with net_device_name = truncate_c_string name }
+  ) net_devices in
+(*
+  If you want to sort by name ...
+  let cmp { net_device_name = n1 } { net_device_name = n2 } = compare n1 n2 in
   let net_devices = List.sort cmp net_devices in
+*)
+
+  (* Get the IPv4 and IPv6 addresses. *)
+  let net_devices = List.map (
+    fun ({ net_device_ip_ptr = ip4 (* pointer to in_device *);
+          net_device_ip6_ptr = ip6 (* pointer to inet6_dev *) } as dev) ->
+      let ip4 =
+       match AddrMap.find ip4 addrmap with
+       | _, Some (_, _, In_device d) ->
+           d.in_device_ifa_list (* pointer to in_ifaddr *)
+       | _ -> assert false in
+      let ip4addrs =
+       let rec loop addr =
+         if addr <> 0L then (
+           let ifaddr =
+             match AddrMap.find addr addrmap with
+             | _, Some (_, _, In_ifaddr d) -> d
+             | _ -> assert false in
+           (ifaddr.in_ifaddr_ifa_address,
+            ifaddr.in_ifaddr_ifa_broadcast,
+            ifaddr.in_ifaddr_ifa_local,
+            ifaddr.in_ifaddr_ifa_mask)
+           :: loop ifaddr.in_ifaddr_ifa_next
+         ) else []
+       in
+       loop ip4 in
+      let ip6 =
+       match AddrMap.find ip6 addrmap with
+       | _, Some (_, _, Inet6_dev d) ->
+           d.inet6_dev_addr_list (* pointer to inet6_ifaddr *)
+       | _ -> assert false in
+      let ip6addrs =
+       let rec loop addr =
+         if addr <> 0L then (
+           let ifaddr =
+             match AddrMap.find addr addrmap with
+             | _, Some (_, _, Inet6_ifaddr d) -> d
+             | _ -> assert false in
+           ifaddr.inet6_ifaddr_prefix_len
+           :: loop ifaddr.inet6_ifaddr_lst_next
+         ) else []
+       in
+       loop ip6 in
+
+      dev, ip4addrs, ip6addrs
+  ) net_devices in
+
+  (* Print out the interfaces and addresses. *)
+  printf
+    "NAME MTU   ADDR             BROADCAST        LOCAL            NETMASK\n";
 
   List.iter (
-    fun netdev ->
-      printf "%5s mtu %Ld\n"
-       netdev.netdev_name
-       netdev.netdev_mtu
+    fun (dev, ip4addrs, ip6addrs) ->
+      printf "%-5s%-6Ld" dev.net_device_name dev.net_device_mtu;
+
+      let rec loop = function
+       | [] -> ()
+       | [addr] -> print addr
+       | addr :: addrs -> print addr; printf "\n           "; loop addrs
+
+      and print (addr, broadcast, local, mask) =
+       printf "%-16s %-16s %-16s %-16s"
+         (string_of_ipv4 addr)
+         (string_of_ipv4 broadcast)
+         (string_of_ipv4 local)
+         (string_of_ipv4 mask)
+
+      and string_of_ipv4 addr =
+       (* Always stored big-endian, even in a little endian kernel: *)
+       let d = Int64.shift_right_logical (Int64.logand addr 0xff000000L) 24
+       and c = Int64.shift_right_logical (Int64.logand addr 0x00ff0000L) 16
+       and b = Int64.shift_right_logical (Int64.logand addr 0x0000ff00L) 8
+       and a =                            Int64.logand addr 0x000000ffL in
+       sprintf "%Ld.%Ld.%Ld.%Ld" a b c d
+      in
+      loop ip4addrs;
+      printf "\n";
+
+      (* XXX ip6addrs too *)
   ) net_devices
 
 let summary = s_"list network interfaces in virtual machine"
@@ -47,4 +133,3 @@ virt-ifconfig prints a network interfaces for virtual machines.
 
 let () =
   Virt_mem.register "ifconfig" summary description ~needs_net_devices:true ~run
-*)