X-Git-Url: http://git.annexia.org/?p=virt-mem.git;a=blobdiff_plain;f=ifconfig%2Fvirt_ifconfig.ml;fp=ifconfig%2Fvirt_ifconfig.ml;h=1d73bc0850529100978338774168f7e08ba2f7ff;hp=b423fe3e2ea3eaae9aceb1fdaecba1a9c3fc0221;hb=ce3a2b6dc35d60e6ac0679b060fd10213c0b4628;hpb=48a85384daa4089f6d310293ab3f8d713740f962 diff --git a/ifconfig/virt_ifconfig.ml b/ifconfig/virt_ifconfig.ml index b423fe3..1d73bc0 100644 --- a/ifconfig/virt_ifconfig.ml +++ b/ifconfig/virt_ifconfig.ml @@ -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 -*)