Skip to content

Commit

Permalink
Update description fetching code for FreeBSD, fix code for OpenBSD.
Browse files Browse the repository at this point in the history
Update from Jason (Xin) Li to reflect changes to the FreeBSD
SIOCGIFDESCR implementation - it now doesn't return an error if the
buffer is too short, it sets the buffer pointer to NULL.  No FreeBSD
release has SIOCGIFDESCR, so this doesn't break on any release.

The loop, trying to increase the buffer size until it's big enough,
works only on FreeBSD, as that's the only OS where you get told what
length to use; OpenBSD clamps the description length at IFDESCRSIZE, so
we just use that.
  • Loading branch information
guyharris committed Apr 28, 2010
1 parent 073a8b3 commit c65292b
Showing 1 changed file with 39 additions and 11 deletions.
50 changes: 39 additions & 11 deletions inet.c
Expand Up @@ -431,26 +431,54 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s >= 0) {
#ifdef __FreeBSD__
/*
* On FreeBSD, if the buffer isn't big enough for the
* description, the ioctl succeeds, but the description
* isn't copied, ifr_buffer.length is set to the description
* length, and ifr_buffer.buffer is set to NULL.
*/
for (;;) {
free(description);
if ((description = malloc(descrlen)) != NULL) {
#ifdef __FreeBSD__
ifrdesc.ifr_buffer.buffer = description;
ifrdesc.ifr_buffer.length = descrlen;
#else /* __FreeBSD__ */
ifrdesc.ifr_data = (caddr_t)description;
#endif /* __FreeBSD__ */
if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0)
break;
#ifdef __FreeBSD__
else if (errno == ENAMETOOLONG)
descrlen = ifrdesc.ifr_buffer.length;
#endif /* __FreeBSD__ */
else
if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
if (ifrdesc.ifr_buffer.buffer ==
description)
break;
else
descrlen = ifrdesc.ifr_buffer.length;
} else {
/*
* Failed to get interface description.
*/
free(description);
description = NULL;
break;
}
} else
break;
}
#else /* __FreeBSD__ */
/*
* The only other OS that currently supports
* SIOCGIFDESCR is OpenBSD, and it has no way
* to get the description length - it's clamped
* to a maximum of IFDESCRSIZE.
*/
if ((description = malloc(descrlen)) != NULL) {
ifrdesc.ifr_data = (caddr_t)description;
if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
/*
* Failed to get interface description.
*/
free(description);
description = NULL;
}
} else
break;
#endif /* __FreeBSD__ */
close(s);
if (description != NULL && strlen(description) == 0) {
free(description);
Expand Down

0 comments on commit c65292b

Please sign in to comment.