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

Reply via email to