I'm trying to rewrite some source code and I have the following function:
tuntap_interface::if_ioctl(u_int32_t cmd, void *arg)
{
dprintf("tuntap: if ioctl: %d\n", (int) (cmd & 0xff));
switch (cmd) {
case SIOCSIFADDR:
{
dprintf("tuntap: if_ioctl: SIOCSIFADDR\n");
/* Unfortunately, ifconfig sets the address family field of an INET
* netmask to zero, which makes early mDNSresponder versions ignore
* the interface. Fix that here. This one is of the category "ugly
* workaround". Dumb Darwin...
*
* Meanwhile, Apple has fixed mDNSResponder, and recent versions of
* Leopard don't need this hack anymore. However, Tiger still has a
* broken version so we leave the hack in for now.
*
* TODO: Revisit when dropping Tiger support.
*
* Btw. If you configure other network interfaces using ifconfig,
* you run into the same problem. I still don't know how to make the
* tap devices show up in the network configuration panel...
*/
ifaddr_t ifa = (ifaddr_t) arg;
if (ifa == NULL)
return 0;
sa_family_t af = ifaddr_address_family(ifa);
if (af != AF_INET)
return 0;
struct ifaliasreq ifra;
int sa_size = sizeof(struct sockaddr);
if (ifaddr_address(ifa, &ifra.ifra_addr, sa_size)
|| ifaddr_dstaddress(ifa, &ifra.ifra_broadaddr, sa_size)
|| ifaddr_netmask(ifa, &ifra.ifra_mask, sa_size)) {
log(LOG_WARNING,
"tuntap: failed to parse interface address.\n");
return 0;
}
// Check that the address family fields match. If not, issue another
// SIOCAIFADDR to fix the entry.
if (ifra.ifra_addr.sa_family != af
|| ifra.ifra_broadaddr.sa_family != af
|| ifra.ifra_mask.sa_family != af) {
log(LOG_INFO, "tuntap: Fixing address family for %s%d\n",
family_name, unit);
snprintf(ifra.ifra_name, sizeof(ifra.ifra_name), "%s%d",
family_name, unit);
ifra.ifra_addr.sa_family = af;
ifra.ifra_broadaddr.sa_family = af;
ifra.ifra_mask.sa_family = af;
do_sock_ioctl(af, SIOCAIFADDR, &ifra);
}
return 0;
}
case SIOCSIFFLAGS:
return 0;
case SIOCGIFSTATUS:
{
struct ifstat *stat = (struct ifstat *) arg;
int len;
char *p;
if (stat == NULL)
return EINVAL;
/* print status */
len = strlen(stat->ascii);
p = stat->ascii + len;
if (open) {
snprintf(p, IFSTATMAX - len, "\topen (pid %u)\n", pid);
} else {
snprintf(p, IFSTATMAX - len, "\tclosed\n");
}
return 0;
}
case SIOCSIFMTU:
{
struct ifreq *ifr = (struct ifreq *) arg;
if (ifr == NULL)
return EINVAL;
ifnet_set_mtu(ifp, ifr->ifr_mtu);
return 0;
}
case SIOCSIFMEDIA:
return 0;
case SIOCGIFMEDIA:
return 0;
case SIOCDIFADDR:
return 0;
}
return EOPNOTSUPP;
}
However when I try to compile, I'm given the following error:
tuntap.cc:934:8: error: invalid application of 'sizeof' to an incomplete type 'struct ifmediareq'
case SIOCGIFMEDIA:
If i comment out the SIOCGIFMEDIA line everything compiles just fine. Any idea what I'm doing wrong? Here's a snippet from my includes as well:
#include "tuntap.h"
#if 0
#define dprintf(...) log(LOG_INFO, __VA_ARGS__)
#else
#define dprintf(...)
#endif
extern "C" {
#include <net/if_media.h>
#include <sys/conf.h>
#include <sys/syslog.h>
#include <sys/param.h>
#include <sys/filio.h>
#include <sys/sockio.h>
#include <sys/fcntl.h>
#include <sys/kpi_socket.h>
#include <sys/kpi_socket.h>
#include <vm/vm_kern.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/if_arp.h>
#include <miscfs/devfs/devfs.h>
}
SIOCGIFMEDIA
is a#define
which hassizeof (struct ifmediareq)
as part of its content.Somehow,
struct ifmediareq
has not been declared. If you don't have a working example, I would start by grepping through all the include files for that structure declaration. Hopefully there will be a comment explaining how it is supposed to work.(I don't see in on my Linux Redhat system.)