原始套接字编程 ping
时间: 2023-11-25 10:48:51 浏览: 99
原始套接字编程是指在应用层直接访问传输层以下的网络协议栈,可以自己构造IP数据包和ICMP数据包等,实现对网络的底层控制。ping是基于ICMP协议的网络工具,用于测试网络连接是否正常。在原始套接字编程中,可以通过构造ICMP数据包来实现ping的功能。具体实现步骤如下:
```c
// 声明头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h>
// 计算校验和
unsigned short checkSum(unsigned short *addr, int len) {
unsigned int sum = 0;
while (len > 1) {
sum += *addr++;
len -= 2;
}
if (len == 1) {
sum += *(unsigned char *)addr;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
// 发送ICMP请求报文
void sendPing(int sockfd, struct sockaddr_in *addr) {
struct icmp icmp;
icmp.icmp_type = ICMP_ECHO;
icmp.icmp_code = 0;
icmp.icmp_id = getpid();
icmp.icmp_seq = 0;
icmp.icmp_cksum = 0;
icmp.icmp_cksum = checkSum((unsigned short *)&icmp, sizeof(icmp));
sendto(sockfd, &icmp, sizeof(icmp), 0, (struct sockaddr *)addr, sizeof(*addr));
}
// 接收ICMP响应报文
int recvPing(int sockfd, struct sockaddr_in *addr) {
char buf[1024];
struct ip *ip = (struct ip *)buf;
struct icmp *icmp;
int len = sizeof(*addr);
int n = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)addr, &len);
icmp = (struct icmp *)(buf + (ip->ip_hl << 2));
if (icmp->icmp_type == ICMP_ECHOREPLY) {
return 1;
}
return 0;
}
// ping主函数
void ping(char *ip) {
int sockfd;
struct sockaddr_in addr;
struct hostent *host;
int count = 4;
int success = 0;
int i;
// 创建原始套接字
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sockfd < 0) {
perror("socket");
exit(1);
}
// 获取目标主机地址
host = gethostbyname(ip);
if (host == NULL) {
perror("gethostbyname");
exit(1);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr = *((struct in_addr *)host->h_addr);
// 发送ICMP请求报文
for (i = 0; i < count; i++) {
sendPing(sockfd, &addr);
if (recvPing(sockfd, &addr)) {
success++;
}
sleep(1);
}
// 输出结果
printf("Ping %s (%s) %d times, success %d times\n", ip, inet_ntoa(addr.sin_addr), count, success);
close(sockfd);
}
```
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)