首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C/C++ getnameinfo ai_family不支持macOS

C/C++ getnameinfo ai_family不支持macOS
EN

Stack Overflow用户
提问于 2022-01-13 22:33:51
回答 2查看 157关注 0票数 0

如果macOS或某些虚拟接口可用,下面的代码将不再在IPv6上工作。

我总是得到错误的getnameinfo() failed: Unknown error (ai_family not supported)

你知道这有什么不对吗?我只需要一个正确的网络接口与ipv4和互联网。

这个问题首先出现在macOS Sierra身上。

代码语言:javascript
复制
#include "jni.h"
#include "bla_nativeclasses_JNISubNetMask.h"
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

static jobjectArray make_row(JNIEnv *env, jsize count, const char* elements[])
{
    jclass stringClass = (*env)->FindClass(env, "java/lang/String");
    jobjectArray row = (*env)->NewObjectArray(env, count, stringClass, 0);
    jsize i;

    for (i = 0; i < count; ++i) {
        (*env)->SetObjectArrayElement(env, row, i, (*env)->NewStringUTF(env, elements[i]));
    }
    return row;
}


JNIEXPORT jobjectArray JNICALL Java_bla_JNISubNetMask_getSubNetMask(JNIEnv *env, jobject jobj){
    struct ifaddrs *ifaddr, *ifa;
    int family, s ,s2;
    int i = 0;
    int count = 0;
    char host[NI_MAXHOST];
    char subnet[NI_MAXHOST];
    char *tmp = NULL;

    const char* net[1000];
    if (getifaddrs(&ifaddr) == -1) {
        perror("getifaddrs");
        exit(EXIT_FAILURE);
    }

    /* Walk through linked list, maintaining head pointer so we can free list later */
    for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa->ifa_addr == NULL)
           continue;

        if (ifa->ifa_addr->sa_family != AF_INET)
            continue;

        s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
        s2 = getnameinfo(ifa->ifa_netmask, sizeof(struct sockaddr_in), subnet, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);

        if (s != 0 || s2 != 0) {
            printf("getnameinfo() failed: %s (%s)\n", gai_strerror(s), gai_strerror(s2));
            exit(EXIT_FAILURE);
        }

        tmp = (char *)malloc(100*sizeof(char));
        strcpy (tmp,ifa->ifa_name);
        net[i++] = tmp;
        tmp = (char *)malloc(100*sizeof(char));
        strcpy (tmp,host);
        net[i++] = tmp;
        tmp = (char *)malloc(100*sizeof(char));
        strcpy (tmp,subnet);
        net[i++] = tmp;
    }

    freeifaddrs(ifaddr);
    count = i;
    jobjectArray jnet = make_row(env, count, net);
    return jnet;
}

我知道已经有了另一个similar question,但我不太明白答案

EN

Stack Overflow用户

回答已采纳

发布于 2022-01-14 15:50:36

我总是得到错误getnameinfo()失败:未知错误(ai_family不支持)

根据代码中该消息的来源,似乎很明显,它是从以下情况中产生的

s2 = getnameinfo(ifa->ifa\_netmask, sizeof(struct sockaddr\_in), subnet, NI\_MAXHOST, NULL, 0, NI\_NUMERICHOST);

错误代码EAI_FAMILY失败,即使前面的

s = getnameinfo(ifa->ifa\_addr, sizeof(struct sockaddr\_in), host, NI\_MAXHOST, NULL, 0, NI\_NUMERICHOST);

成功了。根据特定的错误代码,失败可能是由于将ifa->ifa_netmask->ai_family设置为与AF_INET不同的值,

  • 是一个不同的已知家族,其地址需要更大的地址结构,或者
  • 是一个无效/未知的家族。

我可以想象任何一种可能出现的方式,但无论是哪种方式,我都会将其描述为getifaddrs()返回来自不同地址家族的地址和网络掩码的任何条目的错误。

合理的缓解取决于问题的具体性质。例如,

如果整个条目是无效的,那么您应该检测并跳过它。如果网络掩码数据是以一个getnameinfo().

  • if地址的形式存在,但是系统没有正确地设置家庭,那么您可以尝试检测该情况并在调用之前纠正它--网络掩码是以IPv6地址的形式出现的,然后您可以检测到它并将其作为IPv6地址读取,并确定从哪里出发。结果可能是将IPv4地址编码为IPv6地址,在这种情况下,您可以从后者中提取前者。
  • 如果您可以不使用子网掩码,那么在这种情况下您只需将其虚拟起来,甚至可能将其从方法结果中全部删除。
票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70703927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档