11-02-2011
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:
Quote:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#ifdef __sunos__
#include <sys/sockio.h>
#endif
#define inaddrr(x) (*(struct in_addr *) &ifr->x[sizeof sa.sin_port])
#if defined(__AIX) || defined(_AIX)
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#define SIZE(p) MAX((p).sa_len, sizeof(p))
#else
#define IFRSIZE ((int)(size * sizeof (struct ifreq)))
#endif
int main ()
{
unsigned char *u = NULL;
int sockfd;
int size = 1;
struct ifreq *ifr;
struct ifconf ifc;
struct sockaddr_in sa;
struct arpreq arp;
char macStr[128];
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)))
{
printf ("Error: Unable to open socket.\n");
exit (1);
}
#if defined(__AIX__) || defined(_AIX)
if (ioctl (sockfd, SIOCGSIZIFCONF, &size) == -1)
{
perror("Error getting size of interface :");
exit (1);
}
ifc.ifc_req = (struct ifreq *) malloc (size);
ifc.ifc_len = size;
if (ioctl(sockfd, SIOCGIFCONF, &ifc))
{
printf ("Error: ioctl SIOCFIFCONF.\n");
exit (1);
}
#else
ifc.ifc_len = IFRSIZE;
ifc.ifc_req = NULL;
do
{
++size;
/* realloc buffer size until no overflow occurs */
if (NULL == (ifc.ifc_req = (struct ifreq*)realloc(ifc.ifc_req, IFRSIZE)))
{
printf ("Error: Unable to allocate mememory.\n");
exit (1);
}
ifc.ifc_len = IFRSIZE;
if (ioctl(sockfd, SIOCGIFCONF, &ifc))
{
printf ("Error: ioctl SIOCFIFCONF.\n");
exit (1);
}
} while (IFRSIZE <= ifc.ifc_len);
#endif
ifr = ifc.ifc_req;
while ((char *) ifr < (char *) ifc.ifc_req + ifc.ifc_len)
{
printf("Interface: %s\n", ifr->ifr_name);
printf("IP Address: %s\n", inet_ntoa(inaddrr(ifr_addr.sa_data)));
u = NULL;
#if defined(__linux__) || defined(linux)
if (0 == ioctl(sockfd, SIOCGIFHWADDR, ifr))
u = (unsigned char *) &ifr->ifr_addr.sa_data;
else
{
#endif
arp.arp_pa = ifr->ifr_addr;
if (0 == ioctl (sockfd, SIOCGARP, &arp))
u = (unsigned char *) arp.arp_ha.sa_data;
else
perror ("Error during ioctl");
#if defined(__linux__) || defined(linux)
}
#endif
memset (macStr, 0, sizeof (macStr));
if (u && u[0] + u[1] + u[2] + u[3] + u[4] + u[5])
{
sprintf (macStr, "%2.2X-%2.2X-%2.2X-%2.2X-%2.2X-%2.2X", u[0], u[1], u[2], u[3], u[4], u[5]);
printf ("HW Address: %s", macStr);
}
printf("\n");
#if defined(__AIX) || defined(_AIX)
ifr = ((char *) ifr + sizeof(ifr->ifr_name) + SIZE(ifr->ifr_addr));
#else
++ifr;
#endif
}
close(sockfd);
}
Now the problem is that when I try to execute the executable after compiling, the following output is produced:
Quote:
$ ./ifconfig-a-AIX
Interface: en0
IP Address: 6.3.6.0
Error during ioctl: Invalid argument
Interface: en0
IP Address: 10.20.21.139
Error during ioctl: No such device or address
Interface: lo0
IP Address: 24.3.0.0
Error during ioctl: Invalid argument
Interface: lo0
IP Address: 127.0.0.1
Error during ioctl: No such device or address
Interface: lo0
IP Address: 0.0.0.0
Error during ioctl: Invalid argument
However, the ifconfig -a output is as follows:
Quote:
$ ifconfig -a
en0: flags=7e080863,10<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,CHECKSUM_OFFLOAD,C HECKSUM_SUPPORT,PSEG>
inet 10.20.21.139 netmask 0xffffff00 broadcast 10.20.21.255
lo0: flags=e08084b<UP,BROADCAST,LOOPBACK,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT>
inet 127.0.0.1 netmask 0xff000000 broadcast 127.255.255.255
inet6 ::1/0
tcp_sendspace 65536 tcp_recvspace 65536
The question is what I am doing wrong?
Why is my executable giving me duplicate entries for devices?
Also, why MAC address is not shown for any of the entries?
Thanks for any help.
10 More Discussions You Might Find Interesting
1. Programming
UNIX, gnu cc compiler, SUN Ultra 60
Hello, this is my first post, so please bear with me. I'm currently developing a test environment for a network subsystem that, when live, accesses databases and other network elements.
However, my test environment will be run offline, so I need to fake... (4 Replies)
Discussion started by: j_t_kim
4 Replies
2. UNIX Desktop Questions & Answers
Has anyone over seen this message on bootup? When booting up, I get:
" Warning: lckdioctl: unknown ioctl cmd:5 ".
It scrolls down the screen 5 - 10 times, the I finally get a login. It is also posting to my syslog file. The system came up, but I am still getting the message... (1 Reply)
Discussion started by: Diana
1 Replies
3. Filesystems, Disks and Memory
Hi,
We are running a perl script to upload some data using SQL* Loader. We pipe the data in a http request to SQL*Loader which loads the data to the database. We encounter the error "Inappropirate ioctl for device" when we try to upload huge data. Any solution would be greatly appreciated.... (4 Replies)
Discussion started by: tojaiganesh
4 Replies
4. UNIX for Dummies Questions & Answers
When I try to format a slice in Solaris 10 I get the follow error :confused: :
-bash-3.00# mkfs /dev/dsk/c1d0s5 18877824
Can not determine partition size: Inappropriate ioctl for device
Some format command output:....
AVAILABLE DISK SELECTIONS:
0. c1d0 <DEFAULT cyl 38735 alt 2... (0 Replies)
Discussion started by: spoonman
0 Replies
5. UNIX for Dummies Questions & Answers
Hello,
I have a cron entry:
59 23 * * * . $HOME/.profile;mydate=`date '+%Y%m%d'`;mv filename filename_$mydate
Which works fine interactively, but gives me the following error when it runs in cron:
Your "cron" job on servername
. $HOME/.profile;mydate=`date '+
produced the... (4 Replies)
Discussion started by: steelrose
4 Replies
6. Shell Programming and Scripting
Dear all,
Problem goes like this:
I have a shell script which when run manually runs perfectly.
When same script is executed through a job schdeduler I get an error as Inappropriate ioctl for device and the script fails.
This problems seems quite guiling to me.
Any clues are heartly... (11 Replies)
Discussion started by: RishiPahuja
11 Replies
7. UNIX for Advanced & Expert Users
Hi All,
int ioctl(int d, int request, ...);
Can somebody tell me how does ioctl decides the input parameter: "request".
Sometimes, its SNDCTL_TMR_TIMEBASE or TCGETS
or FIONREAD...etc.
What is the pattern??
I am asking this coz my strace returns this: ... (1 Reply)
Discussion started by: angad.makkar
1 Replies
8. Solaris
For some reason when I try to take a snapshot of the root slice on a particular machine I get an ioctl 22 error. I can't seem to find much on the problem by searching the internet other than some realtime processes such as ntp that use mlock can cause this to happen. I tried running it with truss... (2 Replies)
Discussion started by: ilikecows
2 Replies
9. Programming
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:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>... (4 Replies)
Discussion started by: semash!
4 Replies
10. Shell Programming and Scripting
Sample program tty, this will be get called from my script test_script.
#include <stdio.h>
#include <unistd.h>
#define TTY_NAME_MAX 32
#define STDIN_FILENO 0 /* Standard input. */
int main(void) {
int ret = 0;
char local_device_file;
printf("\npid =... (7 Replies)
Discussion started by: Gajendra_PH
7 Replies