3

How to clear arp cache in linux by program, not by using arp command? Are there library functions avaliable to implement this?

=========================================================================== EDIT

In linux, I want to clear arp cache periodically and send ping packets to find hosts in LAN(by collecting arp response and ICMP reply). As some hosts don't reply ping, I try to receive arp response and ICMP reply in my program. But if arp cache has the IP information, it doesn't send arp request for that IP, and the topology may not be complete. So I want to clear arp cache periodically. How can I clear arp cache periodically in my program?Thanks for your time.

hel
  • 581
  • 10
  • 26
  • Which language are you programming in? For C, you could use the `execv` call. See this answer for a code example: http://stackoverflow.com/a/5460448/579698, For Java see http://stackoverflow.com/a/13991171/579698 – Stanley F. Mar 10 '16 at 07:55
  • Thanks! Yes, for C. The program needs to clear arp cache periodically and do other things. I don't think `execv` can do this.If execute another file, how can I control the process to do other things? – hel Mar 10 '16 at 14:39
  • If you need to do this regularly, you can place your bin in cron.* folder (there is other solutions) – Pierre Mar 10 '16 at 15:00
  • I don't understand. It's in `linux` – hel Mar 10 '16 at 15:02

3 Answers3

2

It turns out it isn't that bad. You have to:

  1. Create a raw socket, if you haven't already. You can do it with an ICMP socket or well, just about any IPPROTO you want. I've tested it with an ICMP socket.

int sd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);

  1. Get a sockaddr of the IP you want to flush from the cache. You can do this with gethostbyname, or a variety of mechanisms. I'll call our address hostaddy

  2. Create an arpreq struct, and make all fields zero except the arp_pa field.

struct arpreq ar; memset(&ar, 0, sizeof(ar)); memcpy(&ar.arp_pa, hostaddy, sizeof( struct sockaddr_in ) );

  1. Call ioctl on the socket and structure, with SIOCDARP.

int ret = ioctl( sd, SIOCDARP, &ar ); if( ret ) fprintf( stderr, "Failed to clear entry.\n" );

  1. Don't forget to close your socket if you don't plan on using it anymore close(sd)

Sources: (1) strace arp -d <ip> (2) https://svn.nmap.org/nmap/libdnet-stripped/src/arp-ioctl.c

Charles Lohr
  • 695
  • 1
  • 8
  • 23
0

ARP cache may be contained in one of the following files (there is no official recommandation):

/proc/net/arp
/etc/networks
/etc/hosts
/etc/ethers

You can access this file by program and do whatever you want with.

Pierre
  • 1,162
  • 12
  • 29
  • Thanks!I edit the question to make it more clearly. Are there functions avaliable to clear arp cache? – hel Mar 10 '16 at 14:52
  • No, you should access to these file with the langage I/O functions you use (`fopen()`, `fread()` in C, etc...) – Pierre Mar 10 '16 at 14:58
0

Here is my example how I made it for python:

import fcntl
import socket
import struct
import ipaddress

def clear_arp(ip, ifname=''):
    while True:
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    
            ip_bytes = int(ipaddress.IPv4Address(ip)).to_bytes(4, byteorder='big')
            fcntl.ioctl(
                sock.fileno(),
                    0x8953, # SIOCDARP
                    struct.pack('hh48s16s', socket.AF_INET, 0, ip_bytes, ifname[:15].encode())
                )
        except OSError as e:
            break
        finally:
            sock.close()

                    struct.pack('hh48s16s', socket.AF_INET, 0, ip_bytes, ifname[:15].encode())
                )
        except OSError as e:
            break
        finally:
            sock.close()
MrHetii
  • 1,315
  • 10
  • 12