How to assign IP address to interface in python?

23,916

Solution 1

Set an address via the older ioctl interface:

import socket, struct, fcntl

SIOCSIFADDR = 0x8916
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


def setIpAddr(iface, ip):
    bin_ip = socket.inet_aton(ip)
    ifreq = struct.pack('16sH2s4s8s', iface, socket.AF_INET, '\x00' * 2, bin_ip, '\x00' * 8)
    fcntl.ioctl(sock, SIOCSIFADDR, ifreq)


setIpAddr('em1', '192.168.0.1')

(setting the netmask is done with SIOCSIFNETMASK = 0x891C)

Ip addresses can be retrieved in the same way: Finding local IP addresses using Python's stdlib

I believe there is a python implementation of Netlink should you want to use that over ioctl

Solution 2

With pyroute2.IPRoute:

from pyroute2 import IPRoute
ip = IPRoute()
index = ip.link_lookup(ifname='em1')[0]
ip.addr('add', index, address='192.168.0.1', mask=24)
ip.close()

With pyroute2.IPDB:

from pyroute2 import IPDB
ip = IPDB()
with ip.interfaces.em1 as em1:
    em1.add_ip('192.168.0.1/24')
ip.release()

Solution 3

You have multiple options to do it from your python program.

One could use the ip tool like you showed. While this is not the best option at all this usualy does the job while being a little bit slow and arkward to program.

Another way would be to do the things ip does on your own by using the kernel netlink interface directly. I know that libnl has some experimental (?) python bindings. This may work but you will have to deal with a lot of low level stuff. I wouldn't recommend this way for simple "set and get" ips but it's the most "correct" and reliable way to do so.

The best way in my opinion (if you only want to set and get ips) would be to use the NetworkManagers dbus interface. While this is very limited and may have its own problems (it might behave not the way you would like it to) this is the most straight forward way if the NetworkManager is running anyway.

So, choose the libnl approach if you want to get your hands dirty, it's clearly superior but also way more work. You may also get away with the NetworkManager dbus interface, depending on your needs and general system setup. Otherwise you can just leave it that way.

Share:
23,916
Mero
Author by

Mero

Updated on August 28, 2020

Comments

  • Mero
    Mero over 3 years

    I have python script that set the IP4 address for my wireless and wired interfaces. So far, I use subprocess command like :

    subprocess.call(["ip addr add local 192.168.1.2/24 broadcast 192.168.1.255 dev wlan0"])
    

    How can I set the IP4 address of an interface using python libraries? and if there is any way to get an already existing IP configurations using python libraries ?

  • Mero
    Mero over 10 years
    Use network manager dbus could be nice and neat way but I don't use network managers and I am setting my networks manually.
  • Luminger
    Luminger over 10 years
    You may be able to use it anyway if the NetworkManager is up and running besides your manual network configuration. But I don't know the API well enough, you would have to dig into it on your own.
  • Mero
    Mero over 10 years
    Thank you very much.This look great.I will test it tonight. Do you know how I can set the default gateway.
  • tMC
    tMC over 10 years
    The default route is specified by the destination address of 0.0.0.0. You can add routes to routing table via ioctl with SIOCADDRT (0x890B). I might suggest you become familiar with Netlink if you're going to do a lot of interfacing with the networking interface.
  • BradHards
    BradHards over 8 years
    Maybe add disclosure of your association with this tool?
  • svinota
    svinota over 8 years
    I wrote it to be used, not to advertise myself :)) But in the case one wanna know, the association should be obvious, I believe.