SIOCGARP to display the entire ARP table.


 
Thread Tools Search this Thread
Top Forums Programming SIOCGARP to display the entire ARP table.
# 1  
Old 08-25-2010
SIOCGARP to display the entire ARP table.

Hello everybody,

I have a working code that displays an entry from a given IP address. but, how can i display the entire ARP table? like the option 'arp -a' of the standard linux program.

This is the code:
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <net/if.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>

char *mac_ntoa(unsigned char *ptr){
static char address[30];
sprintf(address, "%02X:%02X:%02X:%02X:%02X:%02X",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
return(address);
}

int main(int argc, char* argv[]){
int s;

struct arpreq req;
struct hostent *hp;
struct sockaddr_in *sin;

char *host = argv[1];

bzero((caddr_t)&req, sizeof(req));

sin = (struct sockaddr_in *)&req.arp_pa;
sin->sin_family = AF_INET; /* Address Family: Internet */
sin->sin_addr.s_addr = inet_addr(host);

if(sin->sin_addr.s_addr ==-1){
if(!(hp = gethostbyname(host))){
fprintf(stderr, "arp: %s ", host);
herror((char *)NULL);
return(-1);
        }
bcopy((char *)hp->h_addr, (char *)&sin->sin_addr, sizeof(sin->sin_addr));
}

if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("socket() failed.");
exit(-1);
        } /* Socket is opened.*/

strcpy(req.arp_dev, "eth0");

if(ioctl(s, SIOCGARP, (caddr_t)&req) <0){
if(errno == ENXIO){
printf("%s (%s) -- no entry.\n", host, inet_ntoa(sin->sin_addr));
exit(-1);
        } else {
perror("SIOCGARP");
exit(-1);
        }
}
close(s); /* Close the socket, we don't need it anymore. */

printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));

if(req.arp_flags & ATF_COM){
printf("%s ", mac_ntoa(req.arp_ha.sa_data));
        } else {
printf("incomplete");
}

if(req.arp_flags & ATF_PERM){
printf("ATF_PERM");
        }
if(req.arp_flags & ATF_PUBL){
printf("ATF_PUBL");
        }
if(req.arp_flags & ATF_USETRAILERS){
printf("ATF_USETRAILERS");
}

printf("\n");
return(0);
}

I've looked to /usr/src/linux/net/ipv4/arp.c code before posting and can't find anything that tells me how to do it.

Thanks in advance.
# 2  
Old 08-25-2010
The "-a" flag in Linux just changes the output format. I think you're thinking of the windows arp command, where the "/a" flag displays the whole table.

In any case, according to the strace command, linux ARP doesn't use ioctls to get the ARP table -- it slurps it in from the special file /proc/net/arp all in one big read. Try cat /proc/net/arp.

Last edited by Corona688; 08-25-2010 at 01:49 PM..
# 3  
Old 08-25-2010
Hey Corona688,

Again, you were right, it sounds like a fair solution.

I can use sscanf() reading /proc/net/arp and get the same results as with 'arp -an'. While i was looking for a solution, i saw a program which did it with a complex function, reading from devices called '/dev/kmem' and '/dev/vmunix'. Never understood that.

Well, thank you, man!

Last edited by semash!; 08-25-2010 at 05:16 PM..
# 4  
Old 08-25-2010
Quote:
Originally Posted by semash!
While i was looking for a solution, i saw a program which did it with a complex function, reading from devices called '/dev/kmem' and 'dev/vmunix'. Never understood that.
Ew, that sounds very ugly indeed. It's reading raw data directly from kernel memory...
# 5  
Old 08-25-2010
Yeah... Here's part of the function i was talking about, just for sharing and general knowledge...
Code:
struct nlist nl[] = {
#define    X_ARPTAB    0
    { "_arptab" },
#define    X_ARPTAB_SIZE    1
    { "_arptab_size" },
#define    N_SYSMAP    2
    { "_Sysmap" },
#define    N_SYSSIZE    3
    { "_Syssize" },
    { "" },
};

static struct pte *Sysmap;

/*
 * Dump the entire arp table
 */
dump(kernel, mem)
    char *kernel, *mem;
{
    extern int h_errno;
    struct arptab *at;
    struct hostent *hp;
    int bynumber, mf, arptab_size, sz;
    char *host, *malloc();
    off_t lseek();

    if (nlist(kernel, nl) < 0 || nl[X_ARPTAB_SIZE].n_type == 0) {
        fprintf(stderr, "arp: %s: bad namelist\n", kernel);
        exit(1);
    }
    mf = open(mem, O_RDONLY);
    if (mf < 0) {
        fprintf(stderr, "arp: cannot open %s\n", mem);
        exit(1);
    }
    if (kflag) {
        off_t off;

        Sysmap = (struct pte *)
           malloc((u_int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
        if (!Sysmap) {
            fputs("arp: can't get memory for Sysmap.\n", stderr);
            exit(1);
        }
        off = nl[N_SYSMAP].n_value & ~KERNBASE;
        (void)lseek(mf, off, L_SET);
        (void)read(mf, (char *)Sysmap,
            (int)(nl[N_SYSSIZE].n_value * sizeof(struct pte)));
    }
    klseek(mf, (long)nl[X_ARPTAB_SIZE].n_value, L_SET);
    read(mf, &arptab_size, sizeof arptab_size);
    if (arptab_size <= 0 || arptab_size > 1000) {
        fprintf(stderr, "arp: %s: namelist wrong\n", kernel);
        exit(1);
    }
    sz = arptab_size * sizeof (struct arptab);
    at = (struct arptab *)malloc((u_int)sz);
    if (at == NULL) {
        fputs("arp: can't get memory for arptab.\n", stderr);
        exit(1);
    }
    klseek(mf, (long)nl[X_ARPTAB].n_value, L_SET);
    if (read(mf, (char *)at, sz) != sz) {
        perror("arp: error reading arptab");
        exit(1);
    }
    close(mf);
    for (bynumber = 0; arptab_size-- > 0; at++) {
        if (at->at_iaddr.s_addr == 0 || at->at_flags == 0)
            continue;
        if (bynumber == 0)
            hp = gethostbyaddr((caddr_t)&at->at_iaddr,
                sizeof at->at_iaddr, AF_INET);
        else
            hp = 0;
        if (hp)
            host = hp->h_name;
        else {
            host = "?";
            if (h_errno == TRY_AGAIN)
                bynumber = 1;
        }
        printf("%s (%s) at ", host, inet_ntoa(at->at_iaddr));
        if (at->at_flags & ATF_COM)
            ether_print(at->at_enaddr);
        else
            printf("(incomplete)");
        if (at->at_flags & ATF_PERM)
            printf(" permanent");
        if (at->at_flags & ATF_PUBL)
            printf(" published");
        if (at->at_flags & ATF_USETRAILERS)
            printf(" trailers");
        printf("\n");
    }
}



/*
 * Seek into the kernel for a value.
 */
klseek(fd, base, off)
    int fd, off;
    off_t base;
{
    off_t lseek();

    if (kflag) {    /* get kernel pte */
        base &= ~KERNBASE;
        base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
    }
    (void)lseek(fd, base, off);
}

Smilie

You see? It's incomprehensible.
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Search a string and display its location on the entire string and make a text file

I want to search a small string in a large string and find the locations of the string. For this I used grep "string" -ob <file name where the large string is stored>. Now this gives me the locations of that string. Now how do I store these locations in a text file. Please use CODE tags as... (7 Replies)
Discussion started by: ANKIT ROY
7 Replies

2. Shell Programming and Scripting

Bash script to display result in table

My script gives the following result. Is it possible to display the same in table format ? 1. rex_best Latest feeds are not avaialable. The last feed was generated on 2012-05-17 File Name = ekb_best_20120517_010949_665.tar.gz The Number of entry elements = 4209539 2. rex_genre Latest... (2 Replies)
Discussion started by: kishorekumar87
2 Replies

3. AIX

Problem using ioctl (SIOCGIFCONF and SIOCGARP)

I am writing some portable code to print Interface, its IP address, and its MAC (Hardware) address. It is working on three platforms (viz, Linux, Solaris and HP-UX). However, it is creating problems on AIX. The code is as follows: Now the problem is that when I try to execute the... (1 Reply)
Discussion started by: slash_blog
1 Replies

4. UNIX for Advanced & Expert Users

arp questions

Can someone please explain this output to me. Why doesn't ifconfig show the same info? ~ $ arp -a ? (10.71.0.1) at 00:1b:21:2b:eb:0c on eth0 (4 Replies)
Discussion started by: cokedude
4 Replies

5. UNIX for Dummies Questions & Answers

How to send html file in a mail not as an attachment but it should display in the mail in table for

Hi The below script working when we are sending the html as attachment can u please guide how to send thesmae data in table form direct in the mail and not in mail attachment . cat Employee.sql SET VERIFY OFF SET PAGESIZE 200 SET MARKUP HTML ON SPOOL ON PREFORMAT OFF ENTMAP ON - HEAD... (0 Replies)
Discussion started by: mani_isha
0 Replies

6. UNIX for Advanced & Expert Users

Monitoring the arp table

Man page of netlink says: --------------------------------- NETLINK_ARPD For managing the arp table in user space. ---------------------------------- Is it possible to monitor arp table using Netlink? or it's just for manipulating? (1 Reply)
Discussion started by: xyzt
1 Replies

7. Web Development

Display the contents of a table.

Dear Friends, Am an newbie to this domain. I have a table which is filled with contents which i need to be updated with,so am trying to design a flow which would read the data from the table and mail it to me at regular intervals. I could make out the flow using mailx command but want to... (3 Replies)
Discussion started by: gokulj
3 Replies

8. Red Hat

Arp Problem

Dear All i have a linux proxy server which has RHEL-5 64 bit, it has two interfaces, it has the following details eth0=10.200.14.42 eth3=10.201.14.42 default gateway=10.201.14.254 one static route=192.168.0.0/24 gw 10.200.14.254 i am facing a problem when i ping 10.201.14.42 from... (2 Replies)
Discussion started by: surfer24
2 Replies

9. Solaris

ARP Cache

Dear all, We are testing two of our servers for mq series connectivity. The scenario is, when one machine is shutting down it's services there are some scripts that do a dns update, which removes the ip address and relates it to the ip address of the other node on our dns server, and the update... (7 Replies)
Discussion started by: earlysame55
7 Replies
Login or Register to Ask a Question