Browse Source

implemented --lower-level auto for server

root 8 years ago
parent
commit
b30a347c23
5 changed files with 144 additions and 27 deletions
  1. 3 3
      common.cpp
  2. 1 1
      common.h
  3. 121 10
      main.cpp
  4. 13 13
      network.cpp
  5. 6 0
      network.h

+ 3 - 3
common.cpp

@@ -88,7 +88,7 @@ string rule_keep_del[2];
 u64_t keep_rule_last_time=0;
 
 pthread_t keep_thread;
-int keep_thread_created=0;
+int keep_thread_running=0;
 int iptables_gen_add(const char * s,u32_t const_id)
 {
 	string dummy="";
@@ -342,7 +342,7 @@ void myexit(int a)
 {
     if(enable_log_color)
    	printf("%s\n",RESET);
-    if(keep_thread_created)
+    if(keep_thread_running)
     {
 		if(pthread_cancel(keep_thread))
 		{
@@ -523,7 +523,7 @@ int run_command(string command0,char * &output,int flag) {
     {
     	mylog(log_debug,"run_command %s\n",command);
     }
-    static char buf[1024*1024+100];
+    static __thread char buf[1024*1024+100];
     buf[sizeof(buf)-1]=0;
     if(!(in = popen(command, "r"))){
         mylog(level,"command %s popen failed,errno %s\n",command,strerror(errno));

+ 1 - 1
common.h

@@ -99,7 +99,7 @@ const u32_t server_conn_timeout=conv_timeout+10000;//for test
 
 extern int about_to_exit;
 extern pthread_t keep_thread;
-extern int keep_thread_created;
+extern int keep_thread_running;
 
 enum raw_mode_t{mode_faketcp=0,mode_udp,mode_icmp,mode_end};
 extern raw_mode_t raw_mode;

+ 121 - 10
main.cpp

@@ -1432,7 +1432,35 @@ int client_on_raw_recv(conn_info_t &conn_info)
 	}
 	return 0;
 }
+int handle_lower_level(raw_info_t &raw_info)
+{
+	packet_info_t &send_info=raw_info.send_info;
+	packet_info_t &recv_info=raw_info.recv_info;
+
+	if(lower_level_manual)
+	{
+		memset(&send_info.addr_ll,0,sizeof(send_info.addr_ll));
+		send_info.addr_ll.sll_family=AF_PACKET;
+		send_info.addr_ll.sll_ifindex=ifindex;
+		send_info.addr_ll.sll_halen=ETHER_ADDR_LEN;
+		send_info.addr_ll.sll_protocol=htons(ETH_P_IP);
+		memcpy(&send_info.addr_ll.sll_addr,dest_hw_addr,ETHER_ADDR_LEN);
+		 mylog(log_info,"lower level info %x %x\n ",send_info.addr_ll.sll_halen,send_info.addr_ll.sll_protocol);
+	}
+	else
+	{
+	memset(&send_info.addr_ll,0,sizeof(send_info.addr_ll));
+	send_info.addr_ll.sll_family=recv_info.addr_ll.sll_family;
+	send_info.addr_ll.sll_ifindex=recv_info.addr_ll.sll_ifindex;
+	send_info.addr_ll.sll_protocol=recv_info.addr_ll.sll_protocol;
+	send_info.addr_ll.sll_halen=recv_info.addr_ll.sll_halen;
+	memcpy(recv_info.addr_ll.sll_addr,send_info.addr_ll.sll_addr,sizeof(recv_info.addr_ll.sll_addr));
+	//other bytes should be kept zero.
 
+	  mylog(log_info,"lower level info %x %x\n ",send_info.addr_ll.sll_halen,send_info.addr_ll.sll_protocol);
+	}
+	return 0;
+}
 int server_on_raw_recv_multi()
 {
 	char dummy_buf[buf_len];
@@ -1475,6 +1503,12 @@ int server_on_raw_recv_multi()
 
 			send_info.dst_port = recv_info.src_port;
 			send_info.dst_ip = recv_info.src_ip;
+
+			if(lower_level)
+			{
+				handle_lower_level(raw_info);
+			}
+
 			if(data_len==0&&raw_info.recv_info.syn==1&&raw_info.recv_info.ack==0)
 			{
 				send_info.ack_seq = recv_info.seq + 1;
@@ -1539,6 +1573,11 @@ int server_on_raw_recv_multi()
 		send_info.dst_port = recv_info.src_port;
 		send_info.dst_ip = recv_info.src_ip;
 
+		if(lower_level)
+		{
+			handle_lower_level(raw_info);
+		}
+
 		//id_t tmp_oppsite_id=  ntohl(* ((u32_t *)&data[0]));
 		//mylog(log_info,"[%s]handshake1 received %x\n",ip_port,tmp_oppsite_id);
 
@@ -1926,6 +1965,8 @@ int get_src_adress(u32_t &ip)
 
 int client_event_loop()
 {
+
+
 	char buf[buf_len];
 
 	conn_info_t conn_info;
@@ -1935,6 +1976,26 @@ int client_event_loop()
 	packet_info_t &send_info=conn_info.raw_info.send_info;
 	packet_info_t &recv_info=conn_info.raw_info.recv_info;
 
+
+	if(lower_level)
+	{
+		if(lower_level_manual)
+		{
+			//init_ifindex(if_name);
+			memset(&send_info.addr_ll, 0, sizeof(send_info.addr_ll));
+			send_info.addr_ll.sll_family = AF_PACKET;
+			send_info.addr_ll.sll_ifindex = ifindex;
+			send_info.addr_ll.sll_halen = ETHER_ADDR_LEN;
+			send_info.addr_ll.sll_protocol = htons(ETH_P_IP);
+			memcpy(&send_info.addr_ll.sll_addr, dest_hw_addr, ETHER_ADDR_LEN);
+		}
+		else
+		{
+
+			////todo
+		}
+
+	}
 	//printf("?????\n");
 	if(source_ip_uint32==0)
 	{
@@ -1960,7 +2021,7 @@ int client_event_loop()
 	send_info.src_ip = source_ip_uint32;
 
 	int i, j, k;int ret;
-	init_raw_socket();
+
 
 	//init_filter(source_port);
 	send_info.dst_ip=remote_ip_uint32;
@@ -2187,7 +2248,7 @@ int server_event_loop()
 
 
 
-	init_raw_socket();
+	//init_raw_socket();
 	init_filter(local_port);//bpf filter
 
 	epollfd = epoll_create1(0);
@@ -2380,8 +2441,22 @@ int server_event_loop()
 	}
 	return 0;
 }
-void process_lower_level()
+//char lower_level_arg[1000];
+int process_lower_level_arg()
 {
+	lower_level=1;
+	if(strcmp(optarg,"auto")==0)
+	{
+		if(program_mode==server_mode)
+			return 0;
+		else
+		{
+			mylog(log_fatal,"--lower-level auto hasnt be implement at client side,specify it manually\n");
+			myexit(-1);
+		}
+	}
+
+	lower_level_manual=1;
 	if (strchr(optarg, '#') == 0) {
 		mylog(log_fatal,
 				"lower-level parameter invaild,check help page for format\n");
@@ -2399,6 +2474,7 @@ void process_lower_level()
 	for (int i = 0; i < 6; i++) {
 		dest_hw_addr[i] = uint8_t(hw[i]);
 	}
+	return 0;
 }
 void print_help()
 {
@@ -2437,8 +2513,8 @@ void print_help()
 	printf("    --sock-buf            <number>        buf size for socket,>=10 and <=10240,unit:kbyte,default:1024\n");
 	printf("    --seqmode             <number>        seq increase mode for faketcp:\n");
 	printf("                                          0:dont increase\n");
-	printf("                                          1:increase every packet\n");
-	printf("                                          2:increase randomly, about every 3 packets (default)\n");
+	printf("                                          1:increase every packet(default)\n");
+	printf("                                          2:increase randomly, about every 3 packets\n");
 //	printf("\n");
 	printf("    --lower-level         <string>        send packet at OSI level 2, format:'if_name#dest_mac_adress'\n");
 	printf("                                          ie:'eth0#00:23:45:67:89:b9'.Beta.\n");
@@ -2673,7 +2749,9 @@ void process_arg(int argc, char *argv[])
 			}
 			else if(strcmp(long_options[option_index].name,"lower-level")==0)
 			{
-				process_lower_level();
+				process_lower_level_arg();
+				//lower_level=1;
+				//strcpy(lower_level_arg,optarg);
 			}
 			else if(strcmp(long_options[option_index].name,"simple-rule")==0)
 			{
@@ -2761,6 +2839,8 @@ void process_arg(int argc, char *argv[])
 		print_help();
 		myexit(-1);
 	}
+	//if(lower_level)
+		//process_lower_level_arg();
 
 	 mylog(log_info,"important variables: ");
 
@@ -2788,10 +2868,14 @@ void *run_keep(void *none)
 
 	while(1)
 	{
-		sleep(5);
+		sleep(10);
 		keep_iptables_rule();
-		/*if(about_to_exit)
-			break;*/
+		if(about_to_exit)   //just incase it runs forever if there is some bug,not necessary
+		{
+			sleep(10);
+			keep_thread_running=0; //not thread safe ,but wont cause problem
+			break;
+		}
 	}
 	return NULL;
 
@@ -2895,7 +2979,7 @@ void iptables_rule()
 				mylog(log_fatal, "Error creating thread\n");
 				myexit(-1);
 			}
-			keep_thread_created=1;
+			keep_thread_running=1;
 		}
 	}
 	if(generate_iptables_rule)
@@ -2916,9 +3000,30 @@ void iptables_rule()
 
 
 }
+/*
+int test()
+{
+
+	 int fd;
+	 struct ifreq ifr;
+
+	 fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+	 ifr.ifr_addr.sa_family = AF_INET;
+
+	 strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
+
+	 ioctl(fd, SIOCGIFADDR, &ifr);
+
+	 close(fd);
 
+	 printf("%s\n", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
+
+	 return 0;
+}*/
 int main(int argc, char *argv[])
 {
+	printf("%s\n",my_ntoa(0x00ffffff));
 	//auto a=string_to_vec("a b c d ");
 	//printf("%d\n",(int)a.size());
 	//printf("%d %d %d %d",larger_than_u32(1,2),larger_than_u32(2,1),larger_than_u32(0xeeaaeebb,2),larger_than_u32(2,0xeeaaeebb));
@@ -2968,6 +3073,12 @@ int main(int argc, char *argv[])
 	md5((uint8_t*)tmp,strlen(tmp),(uint8_t*)key2);*/
 
 	iptables_rule();
+	init_raw_socket();
+	if(lower_level_manual)
+	{
+		init_ifindex(if_name);
+	}
+
 	if(program_mode==client_mode)
 	{
 		client_event_loop();

+ 13 - 13
network.cpp

@@ -12,7 +12,7 @@ int raw_recv_fd=-1;
 int raw_send_fd=-1;
 u32_t link_level_header_len=0;//set it to 14 if SOCK_RAW is used in socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
 
-int seq_mode=2;
+int seq_mode=1;
 
 int filter_port=-1;
 
@@ -21,13 +21,14 @@ int disable_bpf_filter=0;  //for test only,most time no need to disable this
 u32_t bind_address_uint32=0;
 
 int lower_level=0;
+int lower_level_manual=0;
 int ifindex=-1;
 char if_name[100]="";
 
 unsigned short g_ip_id_counter=0;
 
-unsigned char dest_hw_addr[6]=
-    {0xff,0xff,0xff,0xff,0xff,0xff};
+unsigned char dest_hw_addr[sizeof(sockaddr_ll::sll_addr)]=
+    {0xff,0xff,0xff,0xff,0xff,0xff,0,0};
 //{0x00,0x23,0x45,0x67,0x89,0xb9};
 
 struct sock_filter code_tcp_old[] = {
@@ -194,7 +195,7 @@ int init_raw_socket()
 	        //perror("Failed to create raw_send_fd");
 	        myexit(1);
 	    }
-		init_ifindex(if_name);
+		//init_ifindex(if_name);
 
 	}
 
@@ -364,14 +365,9 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
     else
     {
 
-    	struct sockaddr_ll addr={0};
-    	//memset(&addr,0,sizeof(addr));
+    	struct sockaddr_ll addr={0};  //={0} not necessary
+    	memcpy(&addr,&send_info.addr_ll,sizeof(addr));
 
-    	addr.sll_family=AF_PACKET;
-    	addr.sll_ifindex=ifindex;
-    	addr.sll_halen=ETHER_ADDR_LEN;
-    	addr.sll_protocol=htons(ETH_P_IP);
-    	memcpy(addr.sll_addr,dest_hw_addr,ETHER_ADDR_LEN);
     	ret = sendto(raw_send_fd, send_raw_ip_buf, ip_tot_len ,  0, (struct sockaddr *) &addr, sizeof (addr));
     }
     if(ret==-1)
@@ -455,10 +451,10 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
 	static char recv_raw_ip_buf[buf_len];
 
 	iphdr *  iph;
-	struct sockaddr saddr={0};
+	struct sockaddr_ll saddr={0};
 	socklen_t saddr_size = sizeof(saddr);
 	int flag=0;
-	int recv_len = recvfrom(raw_recv_fd, recv_raw_ip_buf, max_data_len, flag ,&saddr , &saddr_size);
+	int recv_len = recvfrom(raw_recv_fd, recv_raw_ip_buf, max_data_len, flag ,(sockaddr*)&saddr , &saddr_size);
 
 	if(recv_len<0)
 	{
@@ -485,6 +481,10 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
 	recv_info.dst_ip=iph->daddr;
 	recv_info.protocol=iph->protocol;
 
+	if(lower_level)
+	{
+		memcpy(&recv_info.addr_ll,&saddr,sizeof(recv_info.addr_ll));
+	}
 
 
 	if(bind_address_uint32!=0 &&recv_info.dst_ip!=bind_address_uint32)

+ 6 - 0
network.h

@@ -16,9 +16,12 @@ extern u32_t bind_address_uint32;
 extern int disable_bpf_filter;
 
 extern int lower_level;
+extern int lower_level_manual;
 extern char if_name[100];
 extern unsigned char dest_hw_addr[];
 
+extern int ifindex;
+
 struct icmphdr
 {
 	uint8_t type;
@@ -58,6 +61,9 @@ struct packet_info_t  //todo change this to union
 	uint16_t icmp_seq;
 
 	bool has_ts;
+
+	sockaddr_ll addr_ll;
+
 	packet_info_t();
 };