(* Memory info for virtual domains. (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc. http://libvirt.org/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) open Printf open Virt_mem_gettext.Gettext open Virt_mem_utils open Virt_mem_types open Kernel 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 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 (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" let description = s_"\ virt-ifconfig prints a network interfaces for virtual machines. " let () = Virt_mem.register "ifconfig" summary description ~needs_net_devices:true ~run