1

I am trying to get ARP cache through Netlink socket in android. This similar code is working fine in Linux machine, so I try the same code in Android NDK. But when I run this code, recv() gives -1 everytime with the errno of 11. Can anyone know why it is happening? `

struct sockaddr_nl saddr;
    int m_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);


    memset(&saddr, 0, sizeof(saddr));
    saddr.nl_family = AF_NETLINK;
    saddr.nl_pid = getpid();


    if(m_fd<0) {
        fprintf(stderr, "socket error: \n");
        __android_log_print(ANDROID_LOG_ERROR, "LOG", "socket error %d", errno);
        exit(EXIT_FAILURE);
    } else {
        __android_log_print(ANDROID_LOG_ERROR, "LOG", "socket success %d", m_fd);
    }

    struct {
        struct nlmsghdr nlh;
        struct rtmsg rtm;
    } nl_request;

    nl_request.nlh.nlmsg_type = RTM_GETNEIGH;
    nl_request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
    nl_request.nlh.nlmsg_pid = getpid();
    nl_request.nlh.nlmsg_len = sizeof(nl_request);
    nl_request.nlh.nlmsg_seq = 0;
    nl_request.rtm.rtm_family = AF_INET;

    int sent = send(m_fd, &nl_request, sizeof(nl_request), 0);


    if (sent < 0 ) {
        __android_log_print(ANDROID_LOG_ERROR, "LOG", "request error");
        __android_log_print(ANDROID_LOG_ERROR, "LOG", "%d",errno );
//        fprintf(stderr, "request error\n");
//        exit(EXIT_FAILURE);
    }else {
        __android_log_print(ANDROID_LOG_ERROR, "LOG", "request success %d", sent);
    }


    struct nlmsghdr *h;
    int status;
    char resp[1024];

    static char buffer[RECEIVE_BUFFER_LEN] = {0};
    __android_log_print(ANDROID_LOG_ERROR, "LOG", "buffer length: %d",RECEIVE_BUFFER_LEN);
    memset(buffer, 0, sizeof(buffer));


    /* Check for immediate errors */
//    do {
        status = recv(m_fd, &buffer, sizeof(buffer), MSG_DONTWAIT | MSG_PEEK);
        if (status < 0) {
            __android_log_print(ANDROID_LOG_ERROR, "LOG", "recv_len < 0: %d, errno: %d",
                                status, errno);
        } else {
            __android_log_print(ANDROID_LOG_ERROR, "LOG", "recv_len > 0 : %d", status);
        }
//    } while (status < 0 && (errno == EINTR || errno == EAGAIN));

`

When I run this code in Linux, recv() gives the length of received message, but it only not working in android. I am running this code is Android native C++.

1 Answers1

0

Try using rtgenmsg struct instead of rtmsg for your request message? rtmsg is for route message, RTM_GETROUTE. Also try using AF_UNSPEC for regen_family, not AF_INET. For my case, I can run GETNEIGH successfully on Android, up to API 32. Starting from Android T, I'm getting errno 13. Should be something to do with this https://android.googlesource.com/kernel/common/+/bdf56fbea560eea1e9c2793d69ba13cca2596d7d%5E%21/

Qikai Gao
  • 31
  • 1