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.
However, I wonder how I can avoid the race between the two ioctl's I'm
doing. Which lock must I use?
Other comments are welcome, too.
thanks, Joachim
struct ifconf kifc;
struct ifreq *ifr_ip;
struct ifreq *ifr_mask;
struct sockaddr_in *sin_ip;
struct sockaddr_in *sin_mask;
int numifs;
ifr_ip = NULL;
ifr_mask = NULL;
if (do_tcpip_ioctl(SIOCGIFNUM, sizeof(int), (caddr_t)&numifs)) {
rc = OSIF_ERR_PROTO;
goto exit_unlock;
}
kifc.ifc_len = numifs * sizeof(struct ifreq);
/* get IP addresses */
ifr_ip = (struct ifreq *)kmem_zalloc(kifc.ifc_len, KM_SLEEP);
kifc.ifc_buf = (char *)ifr_ip;
if (do_tcpip_ioctl(SIOCGIFCONF, sizeof(struct ifconf), (caddr_t)&kifc)) {
rc = -1;
goto exit_free;
}
/* get IP network masks */
/* CHECK: we need to do two ioctl()s to get IP addresses of interfaces
and their network masks - this is not race-safe! */
ifr_mask = (struct ifreq *)kmem_zalloc(kifc.ifc_len, KM_SLEEP);
kifc.ifc_buf = (char *)ifr_mask;
if (do_tcpip_ioctl(SIOCGIFNETMASK, sizeof(struct ifconf), (caddr_t)&kifc)) {
rc = -1;
goto exit_free;
}
for (numifs = kifc.ifc_len / sizeof(struct ifreq);
numifs > 0;
numifs--, ifr_ip++, ifr_mask++) {
sin_ip = (struct sockaddr_in *)(uintptr_t)&ifr_ip->ifr_addr;
sin_mask = (struct sockaddr_in *)(uintptr_t)&ifr_mask->ifr_addr;
__local_addr_add(ntohl(sin_ip->sin_addr.s_addr),
ntohl(sin_mask->sin_addr.s_addr));
}
--
Joachim Worringen, Software Architect, Dolphin Interconnect Solutions
phone ++49/(0)228/324 08 17 - http://www.dolphinics.com
_______________________________________________
networking-discuss mailing list
[email protected]