ping of death 防御代码 C语言
时间: 2023-08-31 10:37:59 浏览: 138
### 回答1:
以下是一个简单的ping of death攻击防御代码的C语言示例:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#define PACKET_SIZE 4096
#define MAX_WAIT_TIME 5
#define MAX_NO_PACKETS 3
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
int sockfd, datalen = 56;
int nsend = 0, nreceived = 0;
struct sockaddr_in dest_addr;
pid_t pid;
void DieWithError(char *errorMessage) {
perror(errorMessage);
exit(1);
}
unsigned short cal_chksum(unsigned short *addr, int len) {
int nleft = len;
int sum = 0;
unsigned short *w = addr;
unsigned short answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(unsigned char *) (&answer) = *(unsigned char *) w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return answer;
}
void send_packet() {
memset(sendpacket, 0, sizeof(sendpacket));
struct icmp *icmp = (struct icmp *) sendpacket;
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_code = 0;
icmp->icmp_cksum = 0;
icmp->icmp_id = pid;
icmp->icmp_seq = ++nsend;
struct timeval *tval = (struct timeval *) icmp->icmp_data;
gettimeofday(tval, NULL);
icmp->icmp_cksum = cal_chksum((unsigned short *) icmp, datalen + 8);
if (sendto(sockfd, sendpacket, datalen + 8, 0, (struct sockaddr *) &dest_addr, sizeof(dest_addr)) < 0) {
DieWithError("sendto error");
}
}
void recv_packet() {
int n;
socklen_t fromlen;
struct timeval tv;
tv.tv_sec = MAX_WAIT_TIME;
tv.tv_usec = 0;
while (nreceived < nsend) {
fd_set readfd;
FD_ZERO(&readfd);
FD_SET(sockfd, &readfd);
int retval = select(sockfd + 1, &readfd, NULL, NULL, &tv);
if (retval == -1) {
DieWithError("select error");
} else if (retval == 0) {
printf("Request timed out.\n");
break;
} else {
fromlen = sizeof(dest_addr);
if ((n = recvfrom(sockfd, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *) &dest_addr, &fromlen)) < 0) {
DieWithError("recvfrom error");
}
struct iphdr *ip = (struct iphdr *) recvpacket;
struct timeval *tvsend = (struct timeval *) (recvpacket + sizeof(struct iphdr) + sizeof(struct icmp));
struct icmp *icmp = (struct icmp *) (recvpacket + sizeof(struct iphdr));
if (icmp->icmp_type == ICMP_ECHOREPLY && icmp->icmp_id == pid) {
struct timeval tvrecv;
gettimeofday(&tvrecv, NULL);
long rtt = (tvrecv.tv_sec - tvsend->tv_sec) * 1000 +
### 回答2:
Ping of Death(死亡之Ping)是一种网络攻击方式,它是通过发送异常大尺寸的ICMP(Internet Control Message Protocol)封包来造成目标系统崩溃或无法正常工作。为了防范这种攻击,我们可以编写一段C语言的防御代码。
以下是一个简单的防御代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
int main() {
int sockfd;
struct ip *ip_header;
struct icmp *icmp_header;
char packet[4096];
// 创建套接字
if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
perror("socket() error");
exit(1);
}
// 设置套接字选项
int enable = 1;
if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &enable, sizeof(enable)) < 0) {
perror("setsockopt() error");
exit(1);
}
while(1) {
// 接收ICMP封包
if (recv(sockfd, packet, sizeof(packet), 0) < 0) {
perror("recv() error");
exit(1);
}
// 解析IP头部和ICMP头部
ip_header = (struct ip *)packet;
icmp_header = (struct icmp *)(packet + sizeof(struct ip));
// 判断是否是Ping of Death攻击
if (ip_header->ip_len > ntohs(ip_header->ip_len) || ntohs(ip_header->ip_len) == 84) {
printf("Detected Ping of Death attack!\n");
// 进行防御措施,例如丢弃该封包或向源地址发送应答等
}
}
return 0;
}
```
上述代码实现了一个简单的Ping of Death攻击防御程序。它使用原始套接字创建一个监听ICMP封包的套接字,并通过setsockopt函数设置套接字选项,以便接收IP头部和ICMP头部。然后,在一个无限循环中,它会不断接收封包并判断封包的长度是否异常大,如果是则认为是Ping of Death攻击,并进行相应的防御措施,例如丢弃该封包或向源地址发送应答等。
需要注意的是,该防御代码只是一个简单示例,实际的防御过程可能需要更加复杂的逻辑和措施来保护系统免受Ping of Death攻击。此外,编写防御代码需要根据具体的操作系统和编译器进行适配和测试,以确保代码在目标环境中正常运行。
阅读全文