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
_______________________________________________
opensolaris-code mailing list
opensolaris-code@opensolaris.org
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to