Mini Shell

Direktori : /opt/sharedrads/
Upload File :
Current File : //opt/sharedrads/mass_arp_fixer.py

#!/opt/imh-python/bin/python3
"""Mass arps IPs in 'ip addr' excluding lo and venet"""
import re
from subprocess import Popen, run, PIPE, DEVNULL, CalledProcessError
import sys
from netaddr import IPNetwork, IPAddress


def find_gateway(ip_addr: str, mask: str) -> str:
    """Returns gateway based on IP and Mask"""
    # We don't want the .0 address
    return str(IPAddress((int(IPAddress(ip_addr)) & int(IPAddress(mask))) + 1))


def get_active_interfaces() -> dict[str, str]:
    """Runs ip addr and returns dict of output
    with ip cidr and device"""
    try:
        ip_dict = {}
        ip_regex = re.compile('[0-9]+.[0-9]+.[0-9]+.[0-9]+/[0-9]+')
        with Popen(['ip', 'addr'], stdout=PIPE) as ip_addr:
            with Popen(
                ["grep", "inet "],
                stdin=ip_addr.stdout,
                stdout=PIPE,
                encoding='utf-8',
            ) as grep_inet:
                output = grep_inet.stdout.read()
        for line in output.splitlines():
            for ip_addr in ip_regex.findall(line):
                ip_dict[ip_addr] = line.rsplit()[-1].split(':')[0]
        return ip_dict
    except OSError:
        sys.exit("ip addr failed. Check /sbin/ip and /bin/grep")


def arp(ip_addr, gateway, device):
    "Arps with given ip, gateway and device"
    try:
        run(
            ["/sbin/arping", "-c", "2", "-s", ip_addr, gateway, "-I", device],
            stdout=DEVNULL,
            check=True,
        )
    except (CalledProcessError, OSError):
        print(f"Arp failed for {ip_addr}. Check /sbin/arping")


def main():
    """Main function of mass_arp_fixer"""
    interfaces_dict = get_active_interfaces()
    for ip_cidr, device in interfaces_dict.items():
        if '127.0.0.1' in str(ip_cidr):
            continue
        interface = IPNetwork(ip_cidr)
        ip_addr = str(interface.ip)
        mask = str(interface.netmask)
        gateway = find_gateway(ip_addr, mask)
        arp(ip_addr, gateway, device)
        print(ip_addr, gateway, device)


if __name__ == '__main__':
    main()

Zerion Mini Shell 1.0