|
Home > Archive > Unix Programming > June 2004 > ioctl(sockfd, SIOCGIFCONF, &ifc)
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
ioctl(sockfd, SIOCGIFCONF, &ifc)
|
|
| chris 2004-06-26, 10:11 am |
| Below is my code to loop through the ireq structures. The iterface names
seem to get printed fine but something it wrong with the address stuff.
Later on, when I setup my BPF and read() it blocks forever (even if
packets are coming in).
for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
ifr = (struct ifreq *) ptr;
if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr))
len = ifr->ifr_addr.sa_len;
else
len = sizeof(struct sockaddr);
printf("len: %d\n", len);
ptr += sizeof(ifr->ifr_name) + len;
printf("interface: %s\n", ifr->ifr_name);
if (ifr->ifr_addr.sa_family == AF_LINK) {
struct sockaddr_dl *sdl = (struct sockaddr_dl *) &ifr->ifr_addr;
haddr = sdl->sdl_data + sdl->sdl_nlen;
sa = calloc(1, sizeof(struct sockaddr));
if (sdl->sdl_alen)
memcpy(sa, haddr, sdl->sdl_alen);
switch(sa->sa_family) {
case AF_INET:
sin = (struct sockaddr_in *) haddr;
printf("\taddress: %s\n", inet_ntoa(sin->sin_addr));
break;
case AF_INET6:
sin6 = (struct sockaddr_in6 *) haddr;
printf("\taddress: %s\n", inet_ntop(AF_INET6, &sin6->sin6_addr,
ipstr, sizeof(ipstr)));
break;
}
}
ifrcopy = *ifr;
if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0)
errSys("ioctl error while getting interface flags");
if ((ifrcopy.ifr_flags & IFF_UP) && ((ifrcopy.ifr_flags &
IFF_LOOPBACK) == 0)) {
strncpy(ifname, ifr->ifr_name, IFNAMELEN);
break;
}
}
Output:
Aurora:/Users/chris/dev/network/packetsniffer root# ./psinterface: lo0
interface: lo0
interface: lo0
interface: lo0
interface: gif0
interface: stf0
interface: en0
listening on en0
| |
| sean larsson 2004-06-26, 10:11 am |
| heheh hey there netBSD :D the problem is you can't use inet_ntoa() to print out hardware addresses. in your AF_LINK block of code, the addresses provided to you are 6 byte MAC addresses. they are NOT ip addresses. they need to be printed byte by byte,or
by using the ether_ntoa() function. look at the stevens code in the ioctl directory that scorpions gave u a link to. it's in my post.
On Thu, 24 Jun 2004 17:58:28 GMT
chris <chris@misery.net> wrote:
> Below is my code to loop through the ireq structures. The iterface names
> seem to get printed fine but something it wrong with the address stuff.
> Later on, when I setup my BPF and read() it blocks forever (even if
> packets are coming in).
>
> for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
> ifr = (struct ifreq *) ptr;
>
> if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr))
> len = ifr->ifr_addr.sa_len;
> else
> len = sizeof(struct sockaddr);
>
> printf("len: %d\n", len);
> ptr += sizeof(ifr->ifr_name) + len;
>
> printf("interface: %s\n", ifr->ifr_name);
>
> if (ifr->ifr_addr.sa_family == AF_LINK) {
> struct sockaddr_dl *sdl = (struct sockaddr_dl *) &ifr->ifr_addr;
> haddr = sdl->sdl_data + sdl->sdl_nlen;
>
> sa = calloc(1, sizeof(struct sockaddr));
> if (sdl->sdl_alen)
> memcpy(sa, haddr, sdl->sdl_alen);
>
> switch(sa->sa_family) {
> case AF_INET:
> sin = (struct sockaddr_in *) haddr;
> printf("\taddress: %s\n", inet_ntoa(sin->sin_addr));
> break;
> case AF_INET6:
> sin6 = (struct sockaddr_in6 *) haddr;
> printf("\taddress: %s\n", inet_ntop(AF_INET6, &sin6->sin6_addr,
> ipstr, sizeof(ipstr)));
> break;
> }
>
> }
>
> ifrcopy = *ifr;
> if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0)
> errSys("ioctl error while getting interface flags");
>
> if ((ifrcopy.ifr_flags & IFF_UP) && ((ifrcopy.ifr_flags &
> IFF_LOOPBACK) == 0)) {
> strncpy(ifname, ifr->ifr_name, IFNAMELEN);
> break;
> }
> }
>
>
> Output:
>
> Aurora:/Users/chris/dev/network/packetsniffer root# ./psinterface: lo0
> interface: lo0
> interface: lo0
> interface: lo0
> interface: gif0
> interface: stf0
> interface: en0
> listening on en0
>
--
-sean
| |
| chris 2004-06-26, 10:11 am |
| sean larsson wrote:
> heheh hey there netBSD :D the problem is you can't use inet_ntoa() to print out hardware addresses. in your AF_LINK block of code, the addresses provided to you are 6 byte MAC addresses. they are NOT ip addresses. they need to be printed byte by byte,
or by using the ether_ntoa() function. look at the stevens code in the ioctl directory that scorpions gave u a link to. it's in my post.
>
> On Thu, 24 Jun 2004 17:58:28 GMT
> chris <chris@misery.net> wrote:
>
>
>
>
>
Yes thanks, I noticed I was mixing up the AF_LINK stuff with ifr->addr;
check my post on devshed 
| |
| Fletcher Glenn 2004-06-26, 10:11 am |
|
chris wrote:
> Below is my code to loop through the ireq structures. The iterface names
> seem to get printed fine but something it wrong with the address stuff.
> Later on, when I setup my BPF and read() it blocks forever (even if
> packets are coming in).
>
> for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
> ifr = (struct ifreq *) ptr;
>
> if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr))
> len = ifr->ifr_addr.sa_len;
> else
> len = sizeof(struct sockaddr);
>
> printf("len: %d\n", len);
> ptr += sizeof(ifr->ifr_name) + len;
>
> printf("interface: %s\n", ifr->ifr_name);
>
> if (ifr->ifr_addr.sa_family == AF_LINK) {
The line above says that you will only print if the sa_family is
AF_LINK, which neatly excludes either of your switch cases below.
--
Fletcher Glenn
> struct sockaddr_dl *sdl = (struct sockaddr_dl *)
> &ifr->ifr_addr;
> haddr = sdl->sdl_data + sdl->sdl_nlen;
>
> sa = calloc(1, sizeof(struct sockaddr));
> if (sdl->sdl_alen)
> memcpy(sa, haddr, sdl->sdl_alen);
>
> switch(sa->sa_family) {
> case AF_INET:
> sin = (struct sockaddr_in *) haddr;
> printf("\taddress: %s\n", inet_ntoa(sin->sin_addr));
> break;
> case AF_INET6:
> sin6 = (struct sockaddr_in6 *) haddr;
> printf("\taddress: %s\n", inet_ntop(AF_INET6,
> &sin6->sin6_addr, ipstr, sizeof(ipstr)));
> break;
> }
>
> }
>
> ifrcopy = *ifr;
> if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0)
> errSys("ioctl error while getting interface flags");
>
> if ((ifrcopy.ifr_flags & IFF_UP) && ((ifrcopy.ifr_flags &
> IFF_LOOPBACK) == 0)) {
> strncpy(ifname, ifr->ifr_name, IFNAMELEN);
> break;
> }
> }
>
>
> Output:
>
> Aurora:/Users/chris/dev/network/packetsniffer root# ./psinterface: lo0
> interface: lo0
> interface: lo0
> interface: lo0
> interface: gif0
> interface: stf0
> interface: en0
> listening on en0
>
|
|
|
|
|