#!/usr/bin/env python import sys import os import fcntl import socket from struct import pack def getIPAddress(intf): #Borrowed from: #http://stackoverflow.com/questions/24196932/how-can-i-get-the-ip-address-of-eth0-in-python s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR pack('256s', intf[:15]) )[20:24]) def gratuitousArp(intf, ip=None, mac=None): #Adapted from: #https://github.com/krig/send_arp.py/blob/master/send_arp.py sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW) try: sock.bind((intf, socket.SOCK_RAW)) except: print 'Device does not exist: %s' % intf return if not ip: try: ip = getIPAddress(intf) except IOError: print 'No IP for %s' % intf return packed_ip = pack('!4B', *[int(x) for x in ip.split('.')]) if mac: packed_mac = pack('!6B', *[int(x,16) for x in mac.split(':')]) else: packed_mac = sock.getsockname()[4] bcast_mac = pack('!6B', *(0xFF,)*6) zero_mac = pack('!6B', *(0x00,)*6) eth_arp = pack('!H', 0x0806) arp_proto = pack('!HHBBH', 0x0001, 0x0800, 0x0006, 0x0004, 0x0001) arpframe = [ ## ETHERNET # destination MAC addr bcast_mac, # source MAC addr packed_mac, # eth proto eth_arp, ## ARP arp_proto, # sender MAC addr packed_mac, # sender IP addr packed_ip, # target hardware addr bcast_mac, # target IP addr packed_ip ] # send the ARP packet sock.send(''.join(arpframe)) if __name__ == "__main__": if len(sys.argv) > 1: intfs = sys.argv[1:] else: intfs = os.listdir('/sys/class/net/') for intf in intfs: gratuitousArp(intf)