不完整类型'struct ifmediareq'(ioctl)

时间:2015-06-26 18:46:39

标签: c++ networking driver ioctl tun-tap

我正在尝试重写一些源代码,我有以下功能:

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

但是当我尝试编译时,我收到以下错误:

tuntap.cc:934:8: error: invalid application of 'sizeof' to an incomplete type 'struct ifmediareq'
            case SIOCGIFMEDIA:

如果我评论出SIOCGIFMEDIA系列,那么一切都很好。知道我做错了什么吗?这是我的包含的片段:

#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 个答案:

答案 0 :(得分:0)

SIOCGIFMEDIA#define,其sizeof (struct ifmediareq)作为其内容的一部分。

不知何故,struct ifmediareq尚未宣布。如果你没有一个有效的例子,我首先要仔细阅读该结构声明的所有包含文件。希望会有一条评论说明它应该如何运作。

(我没有看到我的Linux Redhat系统。)