HarmonyOS ping IP地址?

操作步骤:

1、P2P链接成功获取到groupOwnerAddr:xxx。

2、通过hdc shell ping ip 提示Permission denied。

如何能通过开发工具ping这个ip或者手机上是否有支持这个功能的软件。

阅读 493
1 个回答

为防止泛洪攻击,网络模块暂不直接提供网络连通性检测能力接口。目前提供用socket实现如下:

1、先区分是ip地址还是address,address需要进行解析为ip地址。

2、创建socketfd和setsockopt。

3、sendto报文和recvfrom报文 进行解析返回最后结果。

核心代码:

std::string ping(const char *ip) {
    OH_LOG_DEBUG(LOG_APP, "Start ping");
    // for store destination address
    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    std::string strip = ip;

    // fill address, set port to 0
    addr.sin_family = AF_INET;
    addr.sin_port = 0;
    if (inet_aton(ip, (struct in_addr *)&addr.sin_addr.s_addr) == 0) {
        OH_LOG_DEBUG(LOG_APP, "bad ip address: %s\n", ip);

        struct hostent *hptr = gethostbyname(ip);
        if (hptr == nullptr) {
            return "Ping " + strip + ": Name does not resolve\n";
        }
        memcpy(&addr.sin_addr, hptr->h_addr, sizeof(hptr->h_addr));
    }
    // create raw socket for icmp protocol
    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
    if (sock == -1) {
        OH_LOG_DEBUG(LOG_APP, "create icmp socket error");
        return "create icmp socket error";
    }
    // set socket timeout option
    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = RECV_TIMEOUT_USEC;
    int ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    if (ret == -1) {
        OH_LOG_DEBUG(LOG_APP, "setsockopt option error");
        return "setsockopt option error";
    }
    double next_ts = get_timestamp();
    int ident = getpid();
    int seq = 1;

    // time to send another packet
    double current_ts = get_timestamp();
    if (current_ts >= next_ts) {
        // send it
        ret = send_echo_request(sock, &addr, ident, seq);
        if (ret == -1) {
            OH_LOG_DEBUG(LOG_APP, "Send failed");

            return "Send failed";
        }
        // update next sendint timestamp to one second later
        next_ts = current_ts + 1;
        // increase sequence number
        seq += 1;
    }
    // try to receive and print reply
    std::string recv_ping_echo_reply = recv_echo_reply(sock, ident, strip);
    if (recv_ping_echo_reply == "") {
        OH_LOG_DEBUG(LOG_APP, "Receive failed");
        return "Receive failed";
    }
    return recv_ping_echo_reply;
}
int send_echo_request(int sock, struct sockaddr_in *addr, int ident, int seq) {
    struct icmp_echo icmp;
    bzero(&icmp, sizeof(icmp));

    // fill header files
    icmp.type = 8;
    icmp.code = 0;
    icmp.ident = htons(ident);
    icmp.seq = htons(seq);

    // fill magic string
    strncpy(icmp.magic, MAGIC, MAGIC_LEN);

    // fill sending timestamp
    icmp.sending_ts = get_timestamp();

    // calculate and fill checksum
    icmp.checksum = htons(calculate_checksum((unsigned char *)&icmp, sizeof(icmp)));

    // send it
    int bytes = sendto(sock, &icmp, sizeof(icmp), 0, (struct sockaddr *)addr, sizeof(*addr));
    if (bytes == -1) {
        return -1;
    }
    return 0;
}
std::string recv_echo_reply(int sock, int ident, const std::string &strip) {
    // allocate buffer
    OH_LOG_DEBUG(LOG_APP, "Start recv_echo_reply");
    unsigned char buffer[IP_BUFFER_SIZE];
    struct sockaddr_in peer_addr;

    // receive another packet
    socklen_t addr_len = sizeof(peer_addr);
    int bytes = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&peer_addr, &addr_len);
    if (bytes == -1) {
        // normal return when timeout
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            OH_LOG_DEBUG(LOG_APP, "errno == EAGAIN || errno == EWOULDBLOCK, timeout, return\n");
            return "";
        }
        OH_LOG_DEBUG(LOG_APP, "recvfrom bytes is -1, return\n");
        return "";
    }
    int ip_header_len = (buffer[0] & 0xf) << 2;
    // find icmp packet in ip packet
    struct icmp_echo *icmp = (struct icmp_echo *)(buffer + ip_header_len);

    // check type
    if (icmp->type != 0 || icmp->code != 0) {
        OH_LOG_DEBUG(LOG_APP, "check type failed\n");
        return "";
    }
    struct ip *iphdr = (struct ip *)buffer; // IP头部

    std::ostringstream stream;
    stream << "Ping " << strip << "(" << inet_ntoa(peer_addr.sin_addr) << "):\n"
           << inet_ntoa(peer_addr.sin_addr) << " seq=" << ntohs(icmp->seq)
           << " ttl=" << static_cast<unsigned int>(iphdr->ip_ttl) << " time=" << std::fixed << std::setprecision(2)
           << (get_timestamp() - icmp->sending_ts) * 1000 << "ms\n";

    OH_LOG_DEBUG(LOG_APP, "stream.str(): %s\n", stream.str().c_str());

    return stream.str();
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
logo
HarmonyOS
子站问答
访问
宣传栏