Preloading IP stack arp table

gregory.menke at gregory.menke at
Thu Oct 13 14:24:31 UTC 2005


We have an application where we want to avoid all arp traffic- easy
enough to suppress it at the driver, but it is necessary to load static
entries into the arp table.

I spent a day crawling around inside the arp routines, finally finding
the "arplookup" function in netinet/if_ether.c, which lets me add static
arp entries- which do work by the way.

The arplookup function is static, so I added a wrapper function down in
if_ether.c that I could extern and call from userspace.  The attached
code shows how it can be used.  You can see there are some macro & type
declaration issues involved.

I think a patch to if_ether.c & if_ether.h which exposes an arplookup
wrapper to manage manipulating arp entries & reconciles the macros &
types would be worthwhile doing- if there isn't already some method of
loading the arp table that I've overlooked.  Before doing that, I'd like
to solicit comments about any issues involved in this approach, and what
alternatives might exist.




	    unsigned char *ipaddr;
	    unsigned char macaddr[ ETHER_ADDR_LEN ];

      } arpstatic[]= { { "", { 0x00, 0xff, 0xff, 0x0, 0x0, 0x20 } },
		       { NULL }};

      int i;

      struct llinfo_arp {
	    void *p1;
	    void *p2;
	    struct	rtentry *la_rt;
	    struct	mbuf *la_hold;		/* last packet until resolved/timeout */
	    long	la_asked;		/* last time we QUERIED for this addr */
#define	rt_expire rt_rmx.rmx_expire

      extern struct llinfo_arp *gdm_arplookup( u_long addr, int create, int proxy);
      extern void rtems_bsdnet_semaphore_obtain();
      extern void rtems_bsdnet_semaphore_release();


      printf("\nPreloading arp table;\n");

      for(i=0; arpstatic[i].ipaddr != NULL; i++)
	    struct llinfo_arp   *la;
	    struct in_addr      itaddr;
	    struct sockaddr_dl  *sdl;
	    struct rtentry      *rt;

	    inet_aton( arpstatic[i].ipaddr, &itaddr );

	    la = gdm_arplookup( itaddr.s_addr, -1, 0);

	    if (la && (rt = la->la_rt) && (sdl = (struct sockaddr_dl *)(rt->rt_gateway)))
	       printf("   arplookup of %s returned la=%08X\n", inet_ntoa(itaddr), (unsigned int)la);

	       memcpy( LLADDR(sdl), arpstatic[i].macaddr, ETHER_ADDR_LEN );
	       sdl->sdl_alen = ETHER_ADDR_LEN;
	       rt->rt_expire = 0;
	       rt->rt_flags  &= ~RTF_REJECT;
	       la->la_asked = 0;
	       la->la_hold = 0;
      printf("\narp table loaded\n");

More information about the users mailing list