ARP Cache

Hello Everyone!
I want to read the ARP cache and read all the mappings of Protocol addreses
with the Corresponding hardware addresses.
Can any one Suggest how to do that with the help of devctl( ) or ioctl( ).
Thanking for any help in Advance.
regards
Nitin

You can use the SIOCGARP ioctl on the /dev/io-net/ip_en
device.

If called with struct arpreq.arp_pa of all zeros, this
tells the stack you’re after all of them, rather than a
particular one. The return value is the number of
entries currently in the cache, so you can call it
once to get an estimate, malloc the required size,
then call it again to pull them all out.

-seanb

Nitin <nitinm4u@hotmail.com> wrote:

Hello Everyone!
I want to read the ARP cache and read all the mappings of Protocol addreses
with the Corresponding hardware addresses.
Can any one Suggest how to do that with the help of devctl( ) or ioctl( ).
Thanking for any help in Advance.
regards
Nitin

hi Sean!
As suggested by u,I tried to read the ARP cache as shown in the attached C
file.
Still it is reading only one entry.
Can u please make it out Where Iam going wrong?
Thank u.
regards
Nitin


begin 666 myarp.c
M(VEN8VQU9&4@/’-T9&EO+F@^“B-I;F-L=61E(#QE<G)N;RYH/@HC:6YC;'5D
M92 :6]C=&PN:#X*(VEN8VQU9&4@/&YE=”]R;W5T92YH/@HC:6YC;‘5D92
M<WES+W-O8VME=“YH/@HC:6YC;'5D92 ;F5T:6YE=”]I;BYH/@HC:6YC;‘5D
M92 ;F5T+VEF7V1L+F@^"@H*:6YT(&UA:6X@" I"GL(’-T<G5C="!A<G!R
M97$@F%R<%]R97$LF%R<#L*(&EN="!S+"!R971V86PL<F5T=F%L,BQC;W5N
M=#L*(’-T<G5C="!S;V-K861D<E]I;B J<VEN.PH@<W1R=6-T(’-O8VMA9&1R
M7V1L(“IS9&P[“B!U;G-I9VYE9”!C:&%R(“IC+“IB=68[“B!A<G!?<F5Q(#T@
M*’-T<G5C=”!A<G!R97$J6UA;&QO8RAS:7IE;V8H<W1R=6-T(&%R<’)E<2DI
M.PH@(&UE;7-E=" H87)P7W)E<2P@,"P@<VEZ96]F
&%R<%]R97$I3L(”!S
M(#T@;W!E;B@B+V1E=B]I;RUN970O:7!?96XB+” P3L(’)E=‘9A;#UI;V-T
M;“AS+”!324]#1T%24"P@&-A9&1R7W0I(&%R<%]R97$I.PH@:68@’)E='9A
M;” ]/2 M,2D*(‘L*("!P<FEN=&8H(D9I<G-T(&EO8W1L(’)E=‘5R;F5D("TQ
M(BD[“B @97AI=” H,"D["B!]"B!E;’-E(’!R:6YT9B@B7&Y4:&5R92!A<F4@
M8W5R<F5N=&QY(" E9"!%;G1R:65S(&EN($%24"!#86-H95QN(BQR971V86PI
M.PH@(&)U9B ](“AU;G-I9VYE9”!C:&%R(“HI;6%L;&]C*’)E='9A;” J(’-I
M>F5O9BAS=’)U8W0@87)P<F5Q2D[“B @(&UE;7-E=” H8G5F+" P+’)E=‘9A
M;" J(’-I>F5O9BAS=’)U8W0@87)P<F5Q
2D["B @<F5T=F%L,CUI;V-T;“AS
M+”!324]#1T%24"P@8G5F3L(&EF("AR971V86PR(#T](“TQ0H@>PH@(’!R
M:6YT9B@B4V5C;VYD(&EO8W1L(’)E=‘5R;F5D("TQ(BD"B @97AI=" H,"D[
M"B!]"B!A<G @/2 H<W1R=6-T(&%R<’)E<2HI8G5F.PH@"B!F;W(H.W)E='9A
M;#XP.W)E='9A;"TM0H@>PD"7-I;B
U8W0@<V]C:V%D9’)?:6XJ
M
29A<G M/F%R<%]P83L@“0H@(” @<V1L(#T@’-T<G5C="!S;V-K861D<E]D
M;"HI)F%R<"T^87)P7VAA.R "7!R:6YT9B@B)7-<;B(L:6YE=%]N=&]A’-I
M;BT^<VEN7V%D9’(I
3L@”@EC(#T@<V1L+3YS9&Q?9&%T82 K(’-D;"T^<V1L
M7VYL96X["B\O(%!R:6YT(‘1H92!A<W-O8VEA=&5D(&AA<F1W87)E(&%D9’)E
M<W,("!P<FEN=&8H(B4R6#HE,E@Z)3)8.B4R6#HE,E@Z)3)87&XB+&-;,%TL
M(&-;,5TL(&-;,ETL(&-;,UTL(&-;-%TL(&-;-5TI.R (&%R<#T@87)P("L@
3,3L
(" @?0H@(" @( D)"GT
( ``
`
end

Nitin <nitinm4u@hotmail.com> wrote:

hi Sean!
As suggested by u,I tried to read the ARP cache as shown in the attached C
file.
Still it is reading only one entry.
Can u please make it out Where Iam going wrong?
Thank u.
regards
Nitin

Here’s a quick and dirty version based on yours. If you notice
you’re still not getting all of them, it’s probably because
sizeof(sockaddr_in) + sizeof(sockaddr_dl) + sizeof(int) > sizeof(struct arpreq)
meaning you’ve under allocated.

-seanb


#include <stdio.h>
#include <errno.h>
#include <ioctl.h>
#include <net/route.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if_dl.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <devctl.h>


int main ( )
{
struct arpreq *arp_req,*arp;
int s, retval,retval2, *flagsp;
struct sockaddr_in *sin;
struct sockaddr_dl *sdl;
unsigned char *c,*buf;
char *lim;

arp_req = (struct arpreq*)malloc(sizeof(struct arpreq));
memset (arp_req, 0, sizeof(arp_req));
s = open("/dev/io-net/ip_en", 0);
retval=ioctl(s, SIOCGARP, (caddr_t) arp_req);
if(retval == -1) {
printf(“First ioctl returned -1”);
exit (0);
}
else
printf("\nThere are currently %d Entries in ARP Cache\n",retval);
buf = (unsigned char *)malloc(retval * sizeof(struct arpreq));
lim = buf + retval * sizeof(struct arpreq);
memset (buf, 0,retval * sizeof(struct arpreq));
if(devctl(s, SIOCGARP, buf, retval * sizeof(struct arpreq), &retval2)) {
printf(“Second ioctl failed\n”);
exit (0);
}

sin = (struct sockaddr_in *)buf;
sdl = (struct sockaddr_dl *)((char *)sin + sin->sin_len);
flagsp = (int *)((char *)sdl + sdl->sdl_len);

while(retval2 && sin->sin_len && sdl->sdl_len && (char )(flagsp + 1) <= lim) {
/
Should check sin->sin_family, sdl->sdl_family */
printf("%s\n",inet_ntoa(sin->sin_addr));
c = sdl->sdl_data + sdl->sdl_nlen;
// Print the associated hardware address
if(*flagsp & ATF_COM)
printf("%2X:%2X:%2X:%2X:%2X:%2X\n",c[0], c[1], c[2], c[3], c[4], c[5]);
else
printf(“incomplete\n”);

sin = (struct sockaddr_in *)(flagsp + 1);
sdl = (struct sockaddr_dl *)((char *)sin + sin->sin_len);
flagsp = (int *)((char *)sdl + sdl->sdl_len);
retval2–;
}

}