Commit 516fd6bb by 郭峰

Merge branch 'feature-1007488' into 'release'

新增gb28181日志10

See merge request !55
parents e3d2b4e8 34258077
...@@ -110,138 +110,79 @@ QString Common::GetLocalIp() { ...@@ -110,138 +110,79 @@ QString Common::GetLocalIp() {
} }
// 计算校验和 // 计算校验和
uint16_t Common::calculateChecksum(uint16_t *buffer, int size) { unsigned short Common::calculate_checksum(void *b, int len) {
uint32_t checksum = 0; unsigned short *buf = (unsigned short *)b;
while (size > 1) { unsigned int sum = 0;
checksum += *buffer++; unsigned short result;
size -= sizeof(uint16_t);
} for (sum = 0; len > 1; len -= 2)
if (size) { sum += *buf++;
checksum += *(uint8_t *)buffer; if (len == 1)
} sum += *(unsigned char *)buf;
checksum = (checksum >> 16) + (checksum & 0xffff); sum = (sum >> 16) + (sum & 0xFFFF);
checksum += (checksum >> 16); sum += (sum >> 16);
return (uint16_t)(~checksum); result = ~sum;
return result;
} }
// 发送 ICMP 请求
bool Common::sendPingRequest(int sockfd, const char *ipAddress, int sequence) {
struct sockaddr_in destAddr;
memset(&destAddr, 0, sizeof(destAddr));
destAddr.sin_family = AF_INET;
inet_pton(AF_INET, ipAddress, &destAddr.sin_addr);
struct ICMPHeader icmpHeader;
icmpHeader.type = ICMP_ECHO;
icmpHeader.code = 0;
icmpHeader.id = getpid() & 0xffff;
icmpHeader.sequence = sequence;
icmpHeader.checksum = 0;
char packet[sizeof(struct ICMPHeader) + 32];
memcpy(packet, &icmpHeader, sizeof(icmpHeader));
memset(packet + sizeof(icmpHeader), 0, 32);
icmpHeader.checksum = calculateChecksum((uint16_t *)packet, sizeof(packet));
memcpy(packet, &icmpHeader, sizeof(icmpHeader));
if (sendto(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&destAddr, sizeof(destAddr)) < 0) { bool Common::pingAddress(const QString &address) {
perror("sendto");
return false;
}
return true;
}
// 接收 ICMP 回复
bool Common::receivePingReply(int sockfd, int sequence) {
char buffer[1024];
struct sockaddr_in srcAddr;
socklen_t srcAddrLen = sizeof(srcAddr);
struct timeval tv;
tv.tv_sec = 2; // 设置超时时间为2秒
tv.tv_usec = 0;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
perror("setsockopt");
return false;
}
ssize_t bytesRead = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&srcAddr, &srcAddrLen); QByteArray && byJsonIp =address.toUtf8();
if (bytesRead < 0) { const char * target= byJsonIp.data();
perror("recvfrom");
return false;
}
struct iphdr *ipHeader = (struct iphdr *)buffer; struct sockaddr_in dest;
struct ICMPHeader *icmpHeader = (struct ICMPHeader *)(buffer + (ipHeader->ihl << 2)); struct hostent *host_entity;
if (icmpHeader->type == ICMP_ECHOREPLY && icmpHeader->sequence == sequence) { // 解析主机名或IP地址
std::cout << "Ping successful!" << std::endl; if ((host_entity = gethostbyname(target)) == NULL) {
return true; perror("gethostbyname");
return false; // 解析失败,返回false
} }
return false; memset(&dest, 0, sizeof(dest));
} dest.sin_family = AF_INET;
bool Common::pingAddress(const QString &address) { dest.sin_addr = *(struct in_addr *)host_entity->h_addr;
QByteArray && byJsonIp =address.toUtf8(); // 创建原始套接字
const char * ipAddress= byJsonIp.data(); int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
if (sock < 0) {
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
ScopeSemaphoreExit guard([sockfd]() {
close(sockfd);
});
if (sockfd < 0) {
perror("socket"); perror("socket");
return 1; return false; // 套接字创建失败,返回false
}
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
int sequence = 1;
if (sendPingRequest(sockfd, ipAddress, sequence)) {
if (receivePingReply(sockfd, sequence)) {
qInfo()<<"Ping to " << ipAddress << " successful!";
return true;
} else {
qInfo()<<"Ping to " << ipAddress << " failed!";
return false;
}
} }
return false;
}
// 获取本机mac // 设置ICMP包头
bool GetLocalMac(const char *eth_inf, char *mac) struct icmphdr icmp_hdr;
{ icmp_hdr.type = ICMP_ECHO; // ICMP Echo Request
struct ifreq ifr; icmp_hdr.code = 0;
int sd; icmp_hdr.un.echo.id = getpid(); // 使用进程ID作为标识符
icmp_hdr.un.echo.sequence = 1;
icmp_hdr.checksum = 0;
bzero(&ifr, sizeof(struct ifreq)); // 计算ICMP校验和
if( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) icmp_hdr.checksum = calculate_checksum(&icmp_hdr, ICMP_HDRLEN);
{
printf("get %s mac address socket creat error\n", eth_inf);
return false;
}
strncpy(ifr.ifr_name, eth_inf, sizeof(ifr.ifr_name) - 1);
if(ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) // 发送ICMP数据包
{ if (sendto(sock, &icmp_hdr, ICMP_HDRLEN, 0, (struct sockaddr *)&dest, sizeof(dest)) <= 0) {
printf("get %s mac address error\n", eth_inf); perror("sendto");
close(sd); close(sock);
return false; return false; // 发送失败,返回false
} }
snprintf(mac, MAC_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x", // 接收ICMP回复
(unsigned char)ifr.ifr_hwaddr.sa_data[0], char buffer[1024];
(unsigned char)ifr.ifr_hwaddr.sa_data[1], struct sockaddr_in recv_addr;
(unsigned char)ifr.ifr_hwaddr.sa_data[2], socklen_t addr_len = sizeof(recv_addr);
(unsigned char)ifr.ifr_hwaddr.sa_data[3],
(unsigned char)ifr.ifr_hwaddr.sa_data[4],
(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
close(sd); if (recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&recv_addr, &addr_len) <= 0) {
perror("recvfrom");
close(sock);
return false; // 接收失败,返回false
}
return true; // 关闭套接字
close(sock);
return true; // 成功,返回true
} }
......
...@@ -30,13 +30,10 @@ ...@@ -30,13 +30,10 @@
#include <linux/route.h> #include <linux/route.h>
#include <ifaddrs.h> #include <ifaddrs.h>
#include <netdb.h> #include <netdb.h>
#include <fcntl.h>
#define NAME_SIZE 8 #define ICMP_HDRLEN 8
#define MAC_SIZE 18 #define PAYLOAD_SIZE 56
#define IP_SIZE 16
#define MASK_SIZE 24
#define GATEWAY_SIZE 24
// ICMP 头部结构体 // ICMP 头部结构体
struct ICMPHeader { struct ICMPHeader {
uint8_t type; // 类型 uint8_t type; // 类型
...@@ -73,11 +70,7 @@ public: ...@@ -73,11 +70,7 @@ public:
QString getVideoDownload(); QString getVideoDownload();
void setVideoDownload(QString videoDownload); void setVideoDownload(QString videoDownload);
uint16_t calculateChecksum(uint16_t *buffer, int size); unsigned short calculate_checksum(void *b, int len) ;
bool sendPingRequest(int sockfd, const char *ipAddress, int sequence);
bool receivePingReply(int sockfd, int sequence);
//确定当前网络接口 //确定当前网络接口
void determine_interface(char *interface); void determine_interface(char *interface);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment