如何通过程序清除linux中的arp缓存,而不是命令

时间:2016-03-10 07:47:18

标签: linux arp

如何清除linux by program中的arp缓存,而不是使用arp命令?是否有可以实现此功能的库函数?

=============================================== ============================ 的修改

linux中,我想定期清除arp cache并发送ping数据包以查找LAN中的主机(通过收集arp响应和ICMP回复)。由于一些主机不回复ping,我尝试在我的程序中接收arp响应和ICMP回复。但是,如果arp cache具有IP信息,则它不会发送该IP的arp请求,并且拓扑可能不完整。所以我想定期清除arp缓存。如何在我的程序中定期清除arp缓存?感谢您的时间。

3 个答案:

答案 0 :(得分:1)

事实证明它并没有那么糟糕。你必须:

  1. 创建一个原始套接字(如果尚未创建)。您可以使用ICMP套接字或井,几乎任何您想要的IPPROTO。我用ICMP插座测试了它。
  2. class MovePlayerToJoinTable < ActiveRecord::Migration def change games = Game.all games.each do |g| g.players.each do |p| query = sanitize_sql_array(['insert into games_players (player_id, game_id) values (?, ?)', p.id, g.id]) connection.execute(query) end end end end

    1. 获取要从缓存中刷新的IP的sockaddr。您可以使用gethostbyname或各种机制执行此操作。我会拨打我们的地址int sd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);

    2. 创建一个arpreq结构,并使所有字段为零,但arp_pa字段除外。

    3. hostaddy

      1. 使用struct arpreq ar; memset(&ar, 0, sizeof(ar)); memcpy(&ar.arp_pa, hostaddy, sizeof( struct sockaddr_in ) );
      2. 在套接字和结构上调用ioctl

        SIOCDARP

        1. 如果您不打算再使用它,请不要忘记关闭套接字int ret = ioctl( sd, SIOCDARP, &ar ); if( ret ) fprintf( stderr, "Failed to clear entry.\n" );
        2. 来源:(1)close(sd) (2)https://svn.nmap.org/nmap/libdnet-stripped/src/arp-ioctl.c

答案 1 :(得分:0)

ARP缓存可能包含在以下某个文件中(没有正式的建议):

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

您可以通过程序访问此文件并执行任何操作。

答案 2 :(得分:0)

以下是我为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()