hel
hel

Reputation: 611

How to clear arp cache in linux by program, not command

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.

Upvotes: 3

Views: 2800

Answers (3)

MrHetii
MrHetii

Reputation: 1495

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()

Upvotes: 0

Charles Lohr
Charles Lohr

Reputation: 919

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

Upvotes: 3

Pierre
Pierre

Reputation: 1174

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.

Upvotes: 0

Related Questions