发送到EINVAL

时间:2017-08-16 15:30:02

标签: android c sendto

我正在Android中制作可执行文件。这将用于发送ARP数据包,但sendto命令与EINVAL失败。 同一段代码正在使用ARM,但在Cortex A9上失败了。  以下是代码段:

int sendArp( const char *iface, const char *src_ip, const char * trgt_ip)
{
    int  status, frame_length, bytes;
    arp_hdr arphdr;
    uint8_t src_mac[6] ={0};
    uint8_t dst_mac[6] ={0};
    uint8_t ether_frame[ARP_LEN] = {0};
    struct addrinfo hints, *res;
    struct sockaddr_in *ipv4;
    struct sockaddr_ll send_struct;
    struct ifreq ifr;
    int sd =-1;
    int recValue = -1;
    pthread_t thread;

    if(iface == NULL || src_ip == NULL || trgt_ip == NULL)
        return -1;

    if ((sd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0) {
        ALOG ("socket() failed ");
        goto out;
    }
    memset (&ifr, 0, sizeof (ifr));
    snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", iface);
    if (ioctl (sd, SIOCGIFHWADDR, &ifr) < 0) {
        ALOG ("ioctl() failed to get source MAC address ");
        goto out;
    }

    // Copy source MAC address.
    memcpy (src_mac, ifr.ifr_hwaddr.sa_data, 6 * sizeof (uint8_t));

    memset (&send_struct, 0, sizeof (send_struct));
    if ((send_struct.sll_ifindex = if_nametoindex (iface)) == 0) {
        ALOG ("if_nametoindex() failed to obtain iface index ");
        goto out;
    }

    memset (dst_mac, 0xff, 6 * sizeof (uint8_t));

    ALOG ("Iface '%s' index='%i', src=%s : dest=%s\n", iface, send_struct.sll_ifindex, src_ip, trgt_ip);

    memset (&hints, 0, sizeof (struct addrinfo));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = hints.ai_flags | AI_CANONNAME;

    if ((status = inet_pton (AF_INET, src_ip, &arphdr.sender_ip)) != 1) {
        fprintf (stderr, "inet_pton() failed for source IP address.\nError message: %s", strerror (status));
        goto out;
    }

    if ((status = getaddrinfo (trgt_ip, NULL, &hints, &res)) != 0) {
        fprintf (stderr, "getaddrinfo() failed - %s\n", strerror (status));
        goto out;
    }
    ipv4 = (struct sockaddr_in *) res->ai_addr;
    memcpy (&arphdr.target_ip, &ipv4->sin_addr, 4 * sizeof (uint8_t));
    freeaddrinfo (res);

    send_struct.sll_family = AF_PACKET;
    send_struct.sll_protocol = htons(ETH_P_ARP);
    send_struct.sll_hatype = htons(ARPHRD_ETHER);
    send_struct.sll_pkttype = (PACKET_BROADCAST);
    memcpy (send_struct.sll_addr, src_mac, 6 * sizeof (uint8_t));
    send_struct.sll_halen = 6;
    send_struct.sll_addr[6] = 0x00;
    send_struct.sll_addr[7] = 0x00;

    arphdr.htype = htons (1);
    arphdr.ptype = htons (ETH_P_IP);
    arphdr.hlen = 6;
    arphdr.plen = 4;

    arphdr.opcode = htons (ARPOP_REQUEST);

    memcpy (&arphdr.sender_mac, src_mac, 6 * sizeof (uint8_t));
    memset (&arphdr.target_mac, 0, 6 * sizeof (uint8_t));
    frame_length = 6 + 6 + 2 + ARP_HDRLEN;

    memcpy (ether_frame, dst_mac, 6 * sizeof (uint8_t));
    memcpy (ether_frame + 6, src_mac, 6 * sizeof (uint8_t));

    ether_frame[12] = ETH_P_ARP / 256;
    ether_frame[13] = ETH_P_ARP % 256;

    memcpy (ether_frame + ETH_HDRLEN, &arphdr, ARP_HDRLEN * sizeof (uint8_t));

    // Send ethernet frame to socket.
    if ((bytes = sendto (sd, ether_frame, frame_length, 0, (struct sockaddr *) &send_struct, sizeof (send_struct))) <= 0) {
        ALOG ("sendto() failed: error=%s", strerror(errno));
        goto out;
    }
    ALOG("ARP sent, bytes[%d]", bytes);

   recValue = arpRecv(sd, (uint8_t*)arphdr.target_ip);
   ALOG("main::thread_ret=%d", recValue);
out:
    if(sd){
        shutdown(sd,2);
        close(sd);
    }
    return recValue;
}

int main(int argc, const char **argv) {
    return sendArp("wlan0", "10.10.10.10", "20.20.20.20");
}

从代码片段中,我收到错误:

sendto() failed

我看到的内核错误是:

packet size is too short (42 <= 62)

我已经尝试修改套接字标志并在代码中玩了很多,但无法找出根本原因。非常感谢任何帮助。

提前致谢。

0 个答案:

没有答案