Get the guest IP address of Virtual Machine

#+SETUPFILE: ~/Dropbox/Doc/Org_Templates/level-1.org

These days, I am developing a small project. One of the convenient functions it provides is that user can access QEMU virtual machine directly via ssh as long as user knows the name of VM.

There are two methods to archive this if user knows the guest’s MAC address:

Using ARP

ARP is a protocol which is used to convert an IP address to MAC Address.

With the ARP, we can get the MAC Address of a machine by its IP address, but what we have known is guest’s MAC address and what we want to know is IP address.

A hack method is to query all IP<->MAC address, then filter them by guest’s MAC.

#!/usr/bin/python

import commands
import sys

def find_ipaddr(mac):
    outtext = commands.getoutput('arp -n')
    for l in outtext.split('\n'):
        if l.split()[2] == mac:
            return l.split()[0]
    return None

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print 'please input MAC Address'
        exit(1)
    ip = find_ipaddr(sys.argv[1])
    if ip:
        print '%s <-> %s' % (sys.argv[1], ip)
    else:
        print '%s <-> None' % (sys.argv[1])

Using GuestAgent

GuestAgent is a tool provided by QEMU official which aims to provide access to a system-level agent via standard QMP commands.

There are many commands available, one of them named “guest-network-get-interfaces”, outputs guest network information we need.

This way is more useful and graceful than using ARP, we can also get the guest’s IP address even if guest is on another subnet.

The following code shows how it works:

Start guest, append following arguments:

-chardev socket,id=qga0,path=/tmp/qga.sock,server,nowait \
-device virtio-serial -device virtserialport,chardev=qga0,name=org.mathslinux.qemu

Or if you want to use libvirt to start guest, append following xml under <device> tag

<channel type='unix'>
  <source mode='bind' path='/tmp/qga.sock'/>
  <target type='virtio' name='org.mathslinux.qemu'/>
</channel>

Then in the guest, run qemu-ga

./qemu-ga -p /dev/virtio-ports/org.mathslinux.qemu

After guest starts, we can fetch its IP address by connecting and sending “guest-network-get-interface” command to unix socket defined above.

#!/usr/bin/python

import socket
import sys

path = '/tmp/qga.sock'

def find_ipaddr(mac):
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    sock.connect(path)

    sock.send('{"execute": "guest-network-get-interfaces"}')
    data = sock.recv(4096)
    for l in eval(data)['return']:
        if l['hardware-address'] == mac:
            ip_list = l['ip-addresses']
            for ip in ip_list:
                if ip['ip-address-type'] == 'ipv4':
                    return ip['ip-address']

    return None

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print 'please input MAC Address'
        exit(1)
    ip = find_ipaddr(sys.argv[1])
    if ip:
        print '%s <-> %s' % (sys.argv[1], ip)
    else:
        print '%s <-> None' % (sys.argv[1])

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦