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() {
}
// 计算校验和
uint16_t Common::calculateChecksum(uint16_t *buffer, int size) {
uint32_t checksum = 0;
while (size > 1) {
checksum += *buffer++;
size -= sizeof(uint16_t);
}
if (size) {
checksum += *(uint8_t *)buffer;
}
checksum = (checksum >> 16) + (checksum & 0xffff);
checksum += (checksum >> 16);
return (uint16_t)(~checksum);
unsigned short Common::calculate_checksum(void *b, int len) {
unsigned short *buf = (unsigned short *)b;
unsigned int sum = 0;
unsigned short result;
for (sum = 0; len > 1; len -= 2)
sum += *buf++;
if (len == 1)
sum += *(unsigned char *)buf;
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
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));
bool Common::pingAddress(const QString &address) {
if (sendto(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&destAddr, sizeof(destAddr)) < 0) {
perror("sendto");
return false;
}
return true;
}
QByteArray && byJsonIp =address.toUtf8();
const char * target= byJsonIp.data();
// 接收 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;
}
struct sockaddr_in dest;
struct hostent *host_entity;
ssize_t bytesRead = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&srcAddr, &srcAddrLen);
if (bytesRead < 0) {
perror("recvfrom");
return false;
// 解析主机名或IP地址
if ((host_entity = gethostbyname(target)) == NULL) {
perror("gethostbyname");
return false; // 解析失败,返回false
}
struct iphdr *ipHeader = (struct iphdr *)buffer;
struct ICMPHeader *icmpHeader = (struct ICMPHeader *)(buffer + (ipHeader->ihl << 2));
memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_addr = *(struct in_addr *)host_entity->h_addr;
if (icmpHeader->type == ICMP_ECHOREPLY && icmpHeader->sequence == sequence) {
std::cout << "Ping successful!" << std::endl;
return true;
}
return false;
}
bool Common::pingAddress(const QString &address) {
QByteArray && byJsonIp =address.toUtf8();
const char * ipAddress= byJsonIp.data();
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
ScopeSemaphoreExit guard([sockfd]() {
close(sockfd);
});
if (sockfd < 0) {
// 创建原始套接字
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
if (sock < 0) {
perror("socket");
return 1;
}
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; // 套接字创建失败,返回false
}
}
return false;
}
// 获取本机mac
bool GetLocalMac(const char *eth_inf, char *mac)
{
struct ifreq ifr;
int sd;
// 设置ICMP包头
struct icmphdr icmp_hdr;
icmp_hdr.type = ICMP_ECHO; // ICMP Echo Request
icmp_hdr.code = 0;
icmp_hdr.un.echo.id = getpid(); // 使用进程ID作为标识符
icmp_hdr.un.echo.sequence = 1;
icmp_hdr.checksum = 0;
bzero(&ifr, sizeof(struct ifreq));
if( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("get %s mac address socket creat error\n", eth_inf);
return false;
}
strncpy(ifr.ifr_name, eth_inf, sizeof(ifr.ifr_name) - 1);
// 计算ICMP校验和
icmp_hdr.checksum = calculate_checksum(&icmp_hdr, ICMP_HDRLEN);
if(ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
{
printf("get %s mac address error\n", eth_inf);
close(sd);
return false;
// 发送ICMP数据包
if (sendto(sock, &icmp_hdr, ICMP_HDRLEN, 0, (struct sockaddr *)&dest, sizeof(dest)) <= 0) {
perror("sendto");
close(sock);
return false; // 发送失败,返回false
}
snprintf(mac, MAC_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char)ifr.ifr_hwaddr.sa_data[0],
(unsigned char)ifr.ifr_hwaddr.sa_data[1],
(unsigned char)ifr.ifr_hwaddr.sa_data[2],
(unsigned char)ifr.ifr_hwaddr.sa_data[3],
(unsigned char)ifr.ifr_hwaddr.sa_data[4],
(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
// 接收ICMP回复
char buffer[1024];
struct sockaddr_in recv_addr;
socklen_t addr_len = sizeof(recv_addr);
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 @@
#include <linux/route.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <fcntl.h>
#define NAME_SIZE 8
#define MAC_SIZE 18
#define IP_SIZE 16
#define MASK_SIZE 24
#define GATEWAY_SIZE 24
#define ICMP_HDRLEN 8
#define PAYLOAD_SIZE 56
// ICMP 头部结构体
struct ICMPHeader {
uint8_t type; // 类型
......@@ -73,11 +70,7 @@ public:
QString getVideoDownload();
void setVideoDownload(QString videoDownload);
uint16_t calculateChecksum(uint16_t *buffer, int size);
bool sendPingRequest(int sockfd, const char *ipAddress, int sequence);
bool receivePingReply(int sockfd, int sequence);
unsigned short calculate_checksum(void *b, int len) ;
//确定当前网络接口
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