[PATCH] using an interface without IP address
Chris Hanson <[email protected]>
| Newsgroups | gmane.comp.security.libnet |
|---|---|
| Message-ID | <[email protected]> |
Date: Thu, 29 Jan 2004 06:21:25 +0100 From: =?iso-8859-1?Q?Fr=E9d=E9ric_Raynal?= <[email protected]> Currently, I still havent found the ioct() giving me all the devices, even those that are down (I even sent a mail to net-linux to get the solution but got no answer). So, results bellow are "normal" Hi, I'm helping out Domenico by co-maintaining libnet for Debian. I have some experience with this, having had to solve this problem for another program. AFAIK, the only way to get all the interfaces is to read and parse "/proc/net/dev". I've attached some code that does this. This code is a fragment from my program. I'm going to try to integrate this into libnet 1.1.1, and if that works I'll send you a patch.
foo.c
(text/x-csrc, 3.1 KB)
/* Use /proc/net/dev if available, since that will give us a list of
all of the interfaces. Otherwise use SIOCGIFCONF, which will at
least give us the interfaces that are up. */
static struct ifreq *
get_interface_list (unsigned int * n_ifcs_return)
{
struct ifreq * ifcs = (proc_interface_list (n_ifcs_return));
return
((ifcs == 0)
? (conf_interface_list (n_ifcs_return))
: ifcs);
}
static struct ifreq *
conf_interface_list (unsigned int * n_ifcs_return)
{
struct ifconf ifc;
unsigned int n_ifcs = 4;
unsigned int n_bytes = ((sizeof (struct ifreq)) * n_ifcs);
(ifc . ifc_len) = n_bytes;
(ifc . ifc_req) = (xmalloc (n_bytes));
while (1)
{
if ((ioctl (kernel_connection, SIOCGIFCONF, (&ifc))) < 0)
{
log_perror ("SIOCGIFCONF");
free (ifc . ifc_req);
return (0);
}
if ((ifc . ifc_len) < n_bytes)
break;
n_ifcs *= 2;
n_bytes = ((sizeof (struct ifreq)) * n_ifcs);
(ifc . ifc_req) = (xrealloc ((ifc . ifc_req), n_bytes));
}
(*n_ifcs_return) = ((ifc . ifc_len) / (sizeof (struct ifreq)));
return (ifc . ifc_req);
}
static struct ifreq *
proc_interface_list (unsigned int * n_ifcs_return)
{
FILE * s = (fopen ("/proc/net/dev", "r"));
if (s == 0)
{
log_perror ("Unable to open /proc/net/dev");
return (0);
}
discard_line (s);
discard_line (s);
{
unsigned int i = 0;
unsigned int n = 4;
struct ifreq * ifcs = (xmalloc ((sizeof (struct ifreq)) * n));
struct ifreq ifc;
while (proc_interface_name (s, (&ifc)))
{
if (i == n)
{
n *= 2;
ifcs = (xrealloc (ifcs, ((sizeof (struct ifreq)) * n)));
}
(ifcs[i++]) = ifc;
}
fclose (s);
(*n_ifcs_return) = i;
return (ifcs);
}
}
static void
discard_line (FILE * s)
{
while (1)
{
int c = (getc (s));
if ((c == EOF) || (c == '\n'))
break;
}
}
#define PIN_GETC(c, s) \
{ \
c = (getc (s)); \
if (c == EOF) \
return (0); \
if (c == '\0') \
{ \
discard_line (s); \
goto restart; \
} \
}
#define PIN_ACCUM(c) \
{ \
if (i < n) \
(name[i++]) = (c); \
else \
{ \
discard_line (s); \
goto restart; \
} \
}
static int
proc_interface_name (FILE * s, struct ifreq * ifc)
{
char * name = (ifc -> ifr_name);
unsigned int n = (sizeof (ifc -> ifr_name));
unsigned int i;
int c;
restart:
do
{
PIN_GETC (c, s);
}
while (isspace (c));
i = 0;
while (1)
{
PIN_ACCUM (c);
PIN_GETC (c, s);
if (isspace (c))
{
if (c != '\n')
discard_line (s);
break;
}
if (c == ':')
{
if (i < n)
/* Might be part of an alias; check. */
{
unsigned int saved_i = i;
while (1)
{
PIN_ACCUM (c);
PIN_GETC (c, s);
if (!isdigit (c))
{
if (c != ':')
/* Not an alias; first colon was name terminator. */
i = saved_i;
if (c != '\n')
discard_line (s);
break;
}
}
}
break;
}
}
if (i < n)
(name[i]) = '\0';
return (1);
}