Я пытаюсь переписать некоторый исходный код, и у меня есть следующая функция:
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>
}
SIOCGIFMEDIA
это #define
у которого есть sizeof (struct ifmediareq)
как часть его содержания.
Так или иначе, struct ifmediareq
не был объявлен. Если у вас нет рабочего примера, я бы начал с просмотра всех включаемых файлов для этого объявления структуры. Надеюсь, будет комментарий, объясняющий, как это должно работать.
(Я не вижу в моей системе Linux Redhat.)