o There are cases when SIOCGIFINDEX is defined, but it doesn't work. When
this happens, don't reject the whole interface, just mark it as index 0. o Removed Pavel's comment about EFAULT and SIGSEGV. EFAULT is a valid return code for cases where the buffer is too small. o Commented out the smart interface list size logic temporarily as it seems Linux 2.0 SIOCGIFCONF doesn't react to ifc_req==NULL sanely. Replaced it by exponential stepping.
This commit is contained in:
parent
fdf33cde1c
commit
c93214d442
2 changed files with 13 additions and 7 deletions
2
TODO
2
TODO
|
@ -2,6 +2,8 @@ Core
|
||||||
~~~~
|
~~~~
|
||||||
* router id
|
* router id
|
||||||
|
|
||||||
|
- use -freg-struct-return ?
|
||||||
|
|
||||||
- fake multipath?
|
- fake multipath?
|
||||||
- config file: symbolic constants?
|
- config file: symbolic constants?
|
||||||
- counters (according to SNMP MIB?)
|
- counters (according to SNMP MIB?)
|
||||||
|
|
|
@ -115,7 +115,8 @@ scan_ifs(struct ifreq *r, int cnt)
|
||||||
|
|
||||||
#ifdef SIOCGIFINDEX
|
#ifdef SIOCGIFINDEX
|
||||||
if (ioctl(if_scan_sock, SIOCGIFINDEX, r) < 0)
|
if (ioctl(if_scan_sock, SIOCGIFINDEX, r) < 0)
|
||||||
{ err = "SIOCGIFINDEX"; goto faulty; }
|
DBG("SIOCGIFINDEX failed: %m\n");
|
||||||
|
else
|
||||||
i.index = r->ifr_ifindex;
|
i.index = r->ifr_ifindex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ static void
|
||||||
scan_if(timer *t)
|
scan_if(timer *t)
|
||||||
{
|
{
|
||||||
struct ifconf ic;
|
struct ifconf ic;
|
||||||
static int last_ifbuf_size;
|
static int last_ifbuf_size = 4*sizeof(struct ifreq);
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
DBG("Scanning interfaces...\n");
|
DBG("Scanning interfaces...\n");
|
||||||
|
@ -140,7 +141,7 @@ scan_if(timer *t)
|
||||||
ic.ifc_ifcu.ifcu_req = r;
|
ic.ifc_ifcu.ifcu_req = r;
|
||||||
ic.ifc_len = last_ifbuf_size;
|
ic.ifc_len = last_ifbuf_size;
|
||||||
res = ioctl(if_scan_sock, SIOCGIFCONF, &ic);
|
res = ioctl(if_scan_sock, SIOCGIFCONF, &ic);
|
||||||
if (res < 0 && errno != EFAULT) /* FIXME: I would sigsegv you if I were kernel at this point */
|
if (res < 0 && errno != EFAULT)
|
||||||
die("SIOCCGIFCONF: %m");
|
die("SIOCCGIFCONF: %m");
|
||||||
if (res < last_ifbuf_size)
|
if (res < last_ifbuf_size)
|
||||||
{
|
{
|
||||||
|
@ -148,18 +149,21 @@ scan_if(timer *t)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ic.ifc_ifcu.ifcu_req = NULL;
|
#ifdef CLEAN_WAY_WORKING_ONLY_ON_LINUX_2_1 /* FIXME */
|
||||||
|
ic.ifc_req = NULL;
|
||||||
ic.ifc_len = 999999999;
|
ic.ifc_len = 999999999;
|
||||||
if (ioctl(if_scan_sock, SIOCGIFCONF, &ic) < 0)
|
if (ioctl(if_scan_sock, SIOCGIFCONF, &ic) < 0)
|
||||||
die("SIOCIFCONF: %m");
|
die("SIOCIFCONF: %m");
|
||||||
if (ic.ifc_len > 100*1024)
|
|
||||||
die("Buf size MUCH too big: %d\n", ic.ifc_len);
|
|
||||||
ic.ifc_len += sizeof(struct ifreq);
|
ic.ifc_len += sizeof(struct ifreq);
|
||||||
if (last_ifbuf_size < ic.ifc_len)
|
if (last_ifbuf_size < ic.ifc_len)
|
||||||
{
|
{
|
||||||
last_ifbuf_size = ic.ifc_len;
|
last_ifbuf_size = ic.ifc_len;
|
||||||
DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
|
DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
last_ifbuf_size *= 2;
|
||||||
|
DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue