Joachim Worringen wrote:
> Joachim Worringen wrote:
>> Greetings,
>>
>> I need to get the addresses and network masks of all IP interfaces from
>> within my driver (thus, within the kernel). This principally works with
>> the code shown below.
>
> Sorry, I was wrong (did not test the code I pasted below, but other
> code); the code in my posting does not work. I need to check this and
> come back.
Ok, took a closer look at net/if.h and sys/sockio.h, and worked out the
code below which seems to work well and does not have a race issue.
However, even with lifc_family set to AF_UNSPEC, it does not return the
loopback "interface". I added it statically for now (I need it); is
there a better way?
thanks, Joachim
struct lifconf kifc;
struct lifreq *ifr_ip;
struct lifreq ifr_mask;
struct sockaddr_in *sin_ip;
struct sockaddr_in *sin_mask;
int numifs;
/* get IP addresses */
kifc.lifc_family = AF_INET;
numifs = 1;
do {
kifc.lifc_len = numifs*sizeof(struct lifreq);
kifc.lifc_buf = (char *)kmem_zalloc(numifs*sizeof(struct lifreq),
KM_SLEEP);
if (!kifc.lifc_buf)
goto exit_unlock;
if (do_tcpip_ioctl(SIOCGLIFCONF, sizeof(struct lifconf),
(caddr_t)&kifc)) {
rc = -1;
osif_warn("SIOCGLIFCONF failed (%p)", kifc.lifc_buf);
goto exit_free;
}
if (kifc.lifc_len == numifs*sizeof(struct lifreq)) {
/* length provided was ok -> got all interface information */
break;
}
kmem_free(kifc.lifc_buf, numifs*sizeof(struct lifreq));
numifs = kifc.lifc_len/sizeof(struct lifreq);
} while(1);
for (ifr_ip = kifc.lifc_req;
numifs > 0;
numifs--, ifr_ip++) {
/* get IP network mask */
bcopy(ifr_ip->lifr_name, &ifr_mask.lifr_name, LIFNAMSIZ);
if (do_tcpip_ioctl(SIOCGLIFNETMASK, sizeof(struct lifreq),
(caddr_t)&ifr_mask)) {
osif_warn("SIOCGIFNETMASK failed for %s", ifr_ip->lifr_name);
continue;
}
sin_ip = (struct sockaddr_in *)(uintptr_t)&ifr_ip->lifr_addr;
sin_mask = (struct sockaddr_in *)(uintptr_t)&ifr_mask.lifr_addr;
/* ntohl() not needed here */
__local_addr_add(sin_ip->sin_addr.s_addr,
sin_mask->sin_addr.s_addr);
osif_debug_log(0, "added if %s", ifr_ip->lifr_name);
}
/* CHECK: loopback if is not returned by SIOCGLIFCONF (even with
AF_UNSPEC instead
of AF_INET, but as it always exists, we add it statically for now. */
__local_addr_add(ntohl(0x7f000001), ntohl(0xffffff00));
exit_free:
kmem_free(kifc.lifc_buf, kifc.lifc_len);
--
Joachim Worringen, Software Architect, Dolphin Interconnect Solutions
phone ++49/(0)228/324 08 17 - http://www.dolphinics.com
_______________________________________________
networking-discuss mailing list
[email protected]