Linux Network Programming
From Teknologisk videncenter
Contents
Find IP address of an interface
c
#include <stdio.h>
#include <unistd.h>
#include <string.h> /* for strncpy */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <getopt.h>
int main(int argc, char *argv[]) {
int fd;
struct ifreq ifr;
if (argc != 2) {
fprintf(stderr,"Usage: %s interface\n",argv[0]);
return(1);
}
fd = socket(AF_INET, SOCK_DGRAM, 0);
/* I want to get an IPv4 IP address */
ifr.ifr_addr.sa_family = AF_INET;
/* I want IP address attached to interfacename in argv[1] */
strncpy(ifr.ifr_name, argv[1], IFNAMSIZ-1);
ioctl(fd, SIOCGIFADDR, &ifr);
close(fd);
/* display result */
printf("%s\n", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
return 0;
}
Python - simple method
Install netifaces either as apt module python3-netifaces or pip module netifaces
#!/usr/bin/python3
import netifaces
interface='eth0'
ipv4=2 # netifaces index for ipv4
def get_ipv4(iface):
interface_list = netifaces.interfaces()
for i in interface_list:
if iface == i:
addresses=netifaces.ifaddresses(iface)
if ipv4 in addresses:
return(addresses[ipv4][0]['addr'])
else:
return("No IPv4 address")
print(get_ipv4(interface))
Python - hangs if interface link down
Install netifaces either as apt module python3-netifaces or pip module netifaces
#!/usr/bin/env python3
# https://gist.github.com/EONRaider/3b7a8ca433538dc52b09099c0ea92745
__author__ = 'EONRaider, keybase.io/eonraider'
import fcntl
import socket
import struct
try:
from netifaces import AF_INET, ifaddresses
except ModuleNotFoundError as e:
raise SystemExit(f"Requires {e.name} module. Run 'pip install {e.name}' "
f"and try again.")
def get_ip_linux(interface: str) -> str:
"""
Uses the Linux SIOCGIFADDR ioctl to find the IP address associated
with a network interface, given the name of that interface, e.g.
"eth0". Only works on GNU/Linux distributions.
Source: https://bit.ly/3dROGBN
Returns:
The IP address in quad-dotted notation of four decimal integers.
"""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
packed_iface = struct.pack('256s', interface.encode('utf_8'))
packed_addr = fcntl.ioctl(sock.fileno(), 0x8915, packed_iface)[20:24]
return socket.inet_ntoa(packed_addr)
def get_ip_cross(interface: str) -> str:
"""
Cross-platform solution that should work under Linux, macOS and
Windows.
"""
return ifaddresses(interface)[AF_INET][0]['addr']
print(get_ip_linux( "eth0")) #Testing module
print(get_ip_cross( "eth0")) #Testing module