Incomplete type 'struct ifmediareq' (ioctl)

716 views Asked by At

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>
}
1

There are 1 answers

0
wallyk On

SIOCGIFMEDIA is a #define which has sizeof (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.)