+ /* first look for the interface information */
+
+ next = buf;
+ while (next < lim)
+ {
+ ifm = (struct if_msghdr *)next;
+ next += ifm->ifm_msglen;
+
+ if (ifm->ifm_version != RTM_VERSION)
+ {
+ report(stderr,
+ GT_("Routing message version %d not understood."),
+ ifm->ifm_version);
+ exit(1);
+ }
+
+ if (ifm->ifm_type == RTM_IFINFO)
+ {
+ sdl = (struct sockaddr_dl *)(ifm + 1);
+
+ if (!(strlen(iname) == sdl->sdl_nlen
+ && strncmp(iname, sdl->sdl_data, sdl->sdl_nlen) == 0))
+ {
+ continue;
+ }
+
+ if ( !(ifm->ifm_flags & IFF_UP) )
+ {
+ /* the interface is down */
+ goto get_ifinfo_end;
+ }
+
+ ifindex = ifm->ifm_index;
+ ifinfo->rx_packets = ifm->ifm_data.ifi_ipackets;
+ ifinfo->tx_packets = ifm->ifm_data.ifi_opackets;
+
+ break;
+ }
+ }
+
+ if (ifindex < 0)
+ {
+ /* we did not find an interface with a matching name */
+ report(stderr, GT_("No interface found with name %s"), iname);
+ goto get_ifinfo_end;
+ }
+
+ /* now look for the interface's IP address */
+
+ next = buf;
+ while (next < lim)
+ {
+ ifam = (struct ifa_msghdr *)next;
+ next += ifam->ifam_msglen;
+
+ if (ifindex > 0
+ && ifam->ifam_type == RTM_NEWADDR
+ && ifam->ifam_index == ifindex)
+ {
+ /* Expand the compacted addresses */
+ info.rti_addrs = ifam->ifam_addrs;
+ rt_xaddrs((char *)(ifam + 1),
+ ifam->ifam_msglen + (char *)ifam,
+ &info);
+
+ /* Check for IPv4 address information only */
+ if (info.rti_info[RTAX_IFA]->sa_family != AF_INET)
+ {
+ continue;
+ }
+
+ rc = 1;
+
+ sin = (struct sockaddr_in *)info.rti_info[RTAX_IFA];
+ if (sin)
+ {
+ ifinfo->addr = sin->sin_addr;
+ }
+
+ sin = (struct sockaddr_in *)info.rti_info[RTAX_NETMASK];
+ if (sin)
+ {
+ ifinfo->netmask = sin->sin_addr;
+ }
+
+ /* note: RTAX_BRD contains the address at the other
+ * end of a point-to-point link or the broadcast address
+ * of non point-to-point link
+ */
+ sin = (struct sockaddr_in *)info.rti_info[RTAX_BRD];
+ if (sin)
+ {
+ ifinfo->dstaddr = sin->sin_addr;
+ }
+
+ break;
+ }
+ }
+
+ if (rc == 0)
+ {
+ report(stderr, GT_("No IP address found for %s"), iname);
+ }
+
+get_ifinfo_end:
+ free(buf);
+ return rc;
+}
+
+#endif /* __FREEBSD_USE_SYSCTL_GET_IFFINFO */
+
+#endif
+