Browse Source

icmp works

wangyu 8 years ago
parent
commit
95a3ff68e1
1 changed files with 149 additions and 16 deletions
  1. 149 16
      main.cpp

+ 149 - 16
main.cpp

@@ -47,7 +47,8 @@ using namespace std;
 
 const int mode_tcp=0;
 const int mode_udp=1;
-int raw_mode=mode_tcp;
+const int mode_icmp=2;
+int raw_mode=mode_icmp;
 
 char local_address[100], remote_address[100],source_address[100];
 int local_port = -1, remote_port = -1;
@@ -325,6 +326,10 @@ int pre_recv(char * data, int &data_len)
 			printf("decrypt fail\n");
 			return -1;
 		}
+		else
+		{
+			printf("decrypt succ\n");
+		}
 	}
 	else
 	{
@@ -745,6 +750,9 @@ struct packet_info_t
 
 	uint32_t ts,ts_ack;
 
+
+	uint16_t icmp_seq;
+
 	bool has_ts;
 
 }g_packet_info_send,g_packet_info_recv;
@@ -895,13 +903,51 @@ int recv_raw_ip(packet_info_t &info,char * &payload,int &payloadlen)
 }
 
 
+struct icmphdr
+{
+	uint8_t type;
+	uint8_t code;
+	uint16_t check_sum;
+	uint16_t id;
+	uint16_t seq;
+};
+
+char send_raw_icmp_buf[buf_len];
+int send_raw_icmp(packet_info_t &info, char * payload, int payloadlen)
+{
+	icmphdr *icmph=(struct icmphdr *) (send_raw_icmp_buf);
+	memset(icmph,0,sizeof(icmphdr));
+	if(prog_mode==client_mode)
+	{
+		icmph->type=8;
+	}
+	else
+	{
+		icmph->type=0;
+	}
+	icmph->code=0;
+	icmph->id=htons(g_packet_info_send.src_port);
+
+	icmph->seq=htons(g_packet_info_send.icmp_seq++);
+
+	memcpy(send_raw_icmp_buf+sizeof(icmphdr),payload,payloadlen);
+
+	icmph->check_sum = csum( (unsigned short*) send_raw_icmp_buf, sizeof(icmphdr)+payloadlen);
+
+	if(send_raw_ip(info,send_raw_icmp_buf,sizeof(icmphdr)+payloadlen)!=0)
+	{
+		return -1;
+	}
+
+	return 0;
+}
 char send_raw_udp_buf[buf_len];
 int send_raw_udp(packet_info_t &info, char * payload, int payloadlen)
 {
 	udphdr *udph=(struct udphdr *) (send_raw_udp_buf
 			+ sizeof(struct pseudo_header));
 
-	memset(udph,0,sizeof(udph));
+	memset(udph,0,sizeof(udphdr));
 	struct pseudo_header *psh = (struct pseudo_header *) (send_raw_udp_buf);
 
 	udph->source = htons(info.src_port);
@@ -934,7 +980,7 @@ int send_raw_udp(packet_info_t &info, char * payload, int payloadlen)
 	return 0;
 }
 char send_raw_tcp_buf[buf_len];
-int send_raw_tcp(packet_info_t &info, char * payload, int payloadlen) {
+int send_raw_tcp(packet_info_t &info, char * payload, int payloadlen) {  //TODO seq increase
 
 	struct tcphdr *tcph = (struct tcphdr *) (send_raw_tcp_buf
 			+ sizeof(struct pseudo_header));
@@ -1199,6 +1245,56 @@ int send_raw_tcp_deprecated(packet_info_t &info,char * payload,int payloadlen)
      return 0;
 }
 
+char recv_raw_icmp_buf[buf_len];
+int recv_raw_icmp(packet_info_t &info, char *&payload, int &payloadlen)
+{
+	char * ip_payload;
+	int ip_payloadlen;
+
+	if(recv_raw_ip(info,ip_payload,ip_payloadlen)!=0)
+	{
+		printf("recv_raw_ip error");
+		return -1;
+	}
+	if(info.protocol!=IPPROTO_ICMP)
+	{
+		//printf("not udp protocol\n");
+		return -1;
+	}
+
+	icmphdr *icmph=(struct icmphdr *) (ip_payload);
+
+	info.src_port=info.dst_port=ntohs(icmph->id);
+
+
+	if(prog_mode==client_mode)
+	{
+		if(icmph->type!=0)
+			return -1;
+	}
+	else
+	{
+		if(icmph->type!=8)
+			return -1;
+	}
+
+	if(icmph->code!=0)
+		return -1;
+
+	unsigned short check = csum( (unsigned short*) ip_payload, ip_payloadlen);
+
+	if(check!=0)
+	{
+		printf("icmp checksum fail %x\n",check);
+		return -1;
+	}
+
+	payload=ip_payload+sizeof(icmphdr);
+	payloadlen=ip_payloadlen-sizeof(icmphdr);
+	printf("get a packet len=%d\n",payloadlen);
+
+    return 0;
+}
 char recv_raw_udp_buf[buf_len];
 int recv_raw_udp(packet_info_t &info, char *&payload, int &payloadlen)
 {
@@ -1556,13 +1652,29 @@ int send_raw(packet_info_t &info,char * payload,int payloadlen)
 {
 	if(raw_mode==mode_tcp) return send_raw_tcp(info,payload,payloadlen);
 	else if(raw_mode==mode_udp) return send_raw_udp(info,payload,payloadlen);
+	else if(raw_mode==mode_icmp) return send_raw_icmp(info,payload,payloadlen);
 }
 int recv_raw(packet_info_t &info,char * &payload,int &payloadlen)
 {
 	if(raw_mode==mode_tcp)  return recv_raw_tcp(info,payload,payloadlen);
 	else if(raw_mode==mode_udp) return recv_raw_udp(info,payload,payloadlen);
+	else if(raw_mode==mode_icmp) return recv_raw_icmp(info,payload,payloadlen);
 }
 
+
+int send_bare_data(packet_info_t &info,char* data,int len)
+{
+	int new_len=len;
+
+	memcpy(send_data_buf,data,len);
+
+	if(pre_send(send_data_buf,new_len)<0)
+	{
+		return -1;
+	}
+	send_raw(info,send_data_buf,new_len);
+	return 0;
+}
 int send_data(packet_info_t &info,char* data,int len,uint32_t id1,uint32_t id2,uint32_t conv_id)
 {
 	int new_len=1+sizeof(my_id)*3+len;
@@ -1629,7 +1741,7 @@ int try_to_list_and_bind(int port)
 	 {
 		 bind_fd=socket(AF_INET,SOCK_STREAM,0);
 	 }
-	 else  if(raw_mode==mode_udp)
+	 else  if(raw_mode==mode_udp||raw_mode==mode_icmp)
 	 {
 		 bind_fd=socket(AF_INET,SOCK_DGRAM,0);
 	 }
@@ -1687,10 +1799,12 @@ int keep_connection_client() //for client
 		anti_replay.re_init(); //  this is not safe
 
 		g_packet_info_send.src_port = client_bind_to_a_new_port();
+		g_packet_info_send.dst_port =g_packet_info_send.src_port ;
 		printf("using port %d\n", g_packet_info_send.src_port);
 
 		g_packet_info_send.src_ip = inet_addr(source_address);
 
+
 		init_filter(g_packet_info_send.src_port);
 
 		if(raw_mode==mode_tcp)
@@ -1709,14 +1823,15 @@ int keep_connection_client() //for client
 
 			send_raw(g_packet_info_send, 0, 0);
 		}
-		else if(raw_mode==mode_udp)
+		else if(raw_mode==mode_udp||raw_mode==mode_icmp)
 		{
 			client_current_state = client_ack_sent;
 			last_state_time = get_current_time();
 			printf("state changed from nothing to ack_sent\n");
 			retry_counter = RETRY_TIME;
+			g_packet_info_send.icmp_seq=0;
 
-			send_raw(g_packet_info_send, (char*)"hello", strlen("hello"));
+			send_bare_data(g_packet_info_send, (char*)"hello", strlen("hello"));
 
 		}
 	}
@@ -1753,9 +1868,9 @@ int keep_connection_client() //for client
 			{
 				send_raw(g_packet_info_send,0,0);
 			}
-			else if(raw_mode==mode_udp)
+			else if(raw_mode==mode_udp||raw_mode==mode_icmp)
 			{
-				send_raw(g_packet_info_send, (char*)"hello", strlen("hello"));
+				send_bare_data(g_packet_info_send, (char*)"hello", strlen("hello"));
 			}
 			last_state_time=get_current_time();
 			printf("retry send ack  counter left:%d\n",retry_counter);
@@ -1842,7 +1957,7 @@ int keep_connection_server()
 		else
 		{
 			retry_counter--;
-			send_hb(g_packet_info_send,my_id,0,const_id);
+			send_hb(g_packet_info_send,my_id,random(),const_id);
 			last_state_time=get_current_time();
 			printf("half heart beat sent<%x>\n",my_id);
 		}
@@ -2081,6 +2196,11 @@ int server_on_raw_recv(packet_info_t &info,char * data,int data_len)
 	{
 		anti_replay.re_init();
 
+		if(raw_mode==mode_icmp)
+		{
+			g_packet_info_send.src_port = info.src_port;;
+		}
+
 		g_packet_info_send.dst_port = info.src_port;
 		g_packet_info_send.dst_ip = info.src_ip;
 
@@ -2106,20 +2226,25 @@ int server_on_raw_recv(packet_info_t &info,char * data,int data_len)
 			retry_counter = RETRY_TIME;
 			last_state_time = get_current_time();
 		}
-		else if(raw_mode==mode_udp)
+		else if(raw_mode==mode_udp||raw_mode==mode_icmp)
 		{
+
 			if(memcmp((char *)"hello",data,strlen("hello"))!=0)
 			{
 				//data[6]=0;
 				printf("not a hello packet %d\n",data,data_len);
 				return 0;
 			}
+			else
+			{
+				printf("got a hello packet\n");
+			}
 
 			printf("sent half heart_beat\n");
 			//send_raw(g_packet_info_send, 0, 0);
-			send_hb(g_packet_info_send,my_id,0,const_id);
+			send_hb(g_packet_info_send,my_id,random(),const_id);
 
-			printf("changed state to server_syn_ack_sent\n");
+			printf("changed state to server_heartbeat_sent_sent\n");
 
 			server_current_state = server_heartbeat_sent;
 			retry_counter = RETRY_TIME;
@@ -2550,7 +2675,7 @@ int server_event_loop()
 	 {
 		 bind_fd=socket(AF_INET,SOCK_STREAM,0);
 	 }
-	 else  if(raw_mode==mode_udp)
+	 else  if(raw_mode==mode_udp||raw_mode==mode_icmp)
 	 {
 		 bind_fd=socket(AF_INET,SOCK_DGRAM,0);
 	 }
@@ -2663,11 +2788,11 @@ int server_event_loop()
 			    memcpy(raw_recv_buf3,data,new_len);
 			    if(data_len!=0)
 			    {
-			    	if(raw_mode==mode_tcp || (raw_mode==mode_udp &&server_current_state!=server_nothing ))
-			    	{
+			    	//if(raw_mode==mode_tcp || ((raw_mode==mode_udp||raw_mode==mode_icmp) &&server_current_state!=server_nothing ))
+			    	//{
 			    	if(pre_recv(raw_recv_buf3,new_len)<0)
 			    		continue;
-			    	}
+			    	//}
 			    }
 
 				server_on_raw_recv(g_packet_info_recv,raw_recv_buf3,new_len);
@@ -2680,6 +2805,8 @@ int server_event_loop()
 
 int main(int argc, char *argv[])
 {
+	srand(time(0));
+
 	if(raw_mode==mode_tcp)
 	{
 		g_packet_info_send.protocol=IPPROTO_TCP;
@@ -2688,9 +2815,15 @@ int main(int argc, char *argv[])
 	{
 		g_packet_info_send.protocol=IPPROTO_UDP;
 	}
+	else if(raw_mode==mode_icmp)
+	{
+		g_packet_info_send.protocol=IPPROTO_ICMP;
+	}
 	init_random_number_fd();
 	const_id=get_true_random_number_nz();
 
+	seq=get_true_random_number_nz();
+
 	g_packet_info_send.ack_seq=get_true_random_number_nz();
 	g_packet_info_send.seq=get_true_random_number_nz();
 	int i, j, k;