⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan_moreip_mac.c

📁 在linux下
💻 C
字号:
#include	<stdio.h>
#include <stdlib.h>
#include	<string.h>
#include <netdb.h>
#include <sys/stat.h>
#include	<sys/types.h>
#include	<sys/socket.h>
#include	<netinet/in.h>
#include	<arpa/inet.h>
#include <sys/time.h>
#include <sys/select.h> 

#define send_MAXSIZE 	50
#define recv_MAXSIZE 	256
#define NBNS_PORT 		137 		//NetBios-ns端口
#define ONE_SCAN_IPNUM 20

struct Q_NETBIOSNS	//Netbios-ns 询问包的结构
{
	unsigned short int tid;		//unsigned short int 占2字节
	unsigned short int flags;		
    	unsigned short int questions;	//=1,表示询问	
    	unsigned short int answerRRS;	//=1,表示回答
	unsigned short int authorityRRS;	
	unsigned short int additionalRRS;		
	unsigned char name[34];	//Queries部分
    	unsigned short int type;		
    	unsigned short int classe;	
};
unsigned   long   Invert_IP(unsigned   long   NormalIp);   	//把IP转换成能直接递增和递减的地址  
int 	Scan_MAC(unsigned long FirstIP, int DELta);
int 	Check_IP(char   *str);
int 	d_num=0;

int main(int argc, char* argv[])
{	
	unsigned   long   FirstIP,SecondIP;    
	int    DELta =0;				//IP差值,即IP个数
	struct sockaddr_in toAddr;   	//sendto中使用的对方地址

	if(argc == 2 )	//用法和输出IP检测正确性
	{		
		if(Check_IP(argv[1]) == 0 )
		{ 
			printf("[%s] is not a valid IPaddress\n", argv[1]);
			return 0;
		}
		FirstIP = inet_addr(argv[1]);	//inet_addr()返回的地址是网络字节二进制格式,类型in_addr_t(无符号的整形)
		SecondIP = inet_addr(argv[1]);  //inet_addr函数把网络主机地址(如192.168.1.10)为网络字节序二进制值,如果参数char *cp无效,函数返回-1
	}
	else if( argc == 3 )
	{		
		if(Check_IP(argv[1]) == 0 || Check_IP(argv[2]) ==0 )
		{			
			if(Check_IP(argv[1]) == 0 )
				printf("[%s] is not a valid IPaddress\n", argv[1]);
			if(Check_IP(argv[2]) == 0 ) 
				printf("[%s] is not a valid IPaddress\n", argv[2]);
			return 0;
		}		
		FirstIP = inet_addr(argv[1]);		//任意的开始地址 // in_addr_t  inet_addr(const char *cp); 
		SecondIP = inet_addr(argv[2]);		//任意的结束地址
	}
	else 
	{
		printf("Usage[1]: %s Start_IP End_IP",argv[0]);
		printf("\t\t//Start_IP must be smaller than End_IP//\n");
		printf("Usage[2]: %s One_IP\n",argv[0]);
		return 0;
	}

	//FirstIP= inet_addr("192.168.48.129");		//任意的开始地址  
	//SecondIP= inet_addr("192.168.48.137");		//任意的结束地址
	
	//转换成能直接递增和递减的地址  
       FirstIP = Invert_IP(FirstIP);  
       SecondIP = Invert_IP(SecondIP);   
	if( SecondIP < FirstIP)
	{
		printf("[%s] is smaller than [%s]\n", argv[1],argv[2]);
		return 0;
	}
	DELta = SecondIP - FirstIP +1;
	int i = 0;
	//每次群发20个不同IP#define ONE_SCAN_IPNUM 20
	//次数是商QUET_NUM,最后一次群发REMANIND_NUM次。
	int QUET_NUM=DELta/ONE_SCAN_IPNUM;
	int REMANIND_NUM= DELta%ONE_SCAN_IPNUM;
	printf(" Start to scan MAC......\n",DELta+1);
	printf(" %-16s%-16s%-16s%-16s\n","IP Address","HOST Name","GROUP Name","MAC Address");
	for(i=0;i<QUET_NUM+1;i++)
	{		
		//printf("循环次数:%d\n",i);
		if(i==QUET_NUM)
			Scan_MAC(FirstIP,REMANIND_NUM);
		else
			Scan_MAC(FirstIP,ONE_SCAN_IPNUM);
		//sleep(1000);
	
		
	}
	if(QUET_NUM!=0)
		printf(" %-16s%-16s%-16s%-16s\n","The Others","N/A","N/A","N/A");

	
}

//Check_IP 返回1,则IP正确;返回0,IP错误
int Check_IP(char * str)
{	
	int dot_count =0;
	int num_count = 0;
	//printf("%s\n",str);
	while( (*str) != '\0' )
	{
		if((*str) != '.')
		{
			if( (*str) <= '9' && (*str) >='0')
			{
				num_count = num_count*10+(int)(*str)-'0';
				if( num_count <0 || num_count >255 )
					return 0;
			}
			else
				return 0;
			
		}
		else
		{
			if( num_count ==0 && dot_count ==0 )
				return 0;
			dot_count++;
			if( num_count <0 || num_count >255 )
				return 0;
			num_count =0;//reset num_count to 0
		}
		str++;
	}
	if( dot_count != 3)
		return 0;
	return 1;
}

//把网络字节格式IP转换成能直接递增和递减的长整型 
//
unsigned   long   Invert_IP(unsigned   long   NormalIp)//把字节序颠倒
{
      unsigned  char b1,b2,b3,b4;  
      b1 =  NormalIp & 0x00FF;  
      b2 =  (NormalIp >> 8) & 0x00FF;  
      b3 =  (NormalIp >> 16) & 0x00FF;  
      b4 =  (NormalIp >> 24) & 0x00FF;  
      return   (b1 << 24) |(b2 << 16) |(b3 << 8) |b4;  
}

//scan 有问题,一次循环为什么只有一个结果输出
//
int Scan_MAC(unsigned long FirstIP, int NUM)
{
	unsigned long TempStartIP = FirstIP;
	int sockfd;	//socket
	char send_buff[send_MAXSIZE];
	char recv_buff[recv_MAXSIZE];
	memset(send_buff,0,sizeof(send_buff)); 
	memset(recv_buff,0,sizeof(recv_buff)); 

	//构造netbios-ns-udp询问包结构
	//char  sendbuff[]="\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x20\x43\x4b\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x00\x00\x21\x00\x01";

	if( (sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0)
	{
		//printf("socket error\n");
		return 0;
	}
	
	//用一个socket  循环发送netbios-ns包
	int k=0;
	for(k=0;k<NUM;k++)
	{
		struct Q_NETBIOSNS nbns;

		nbns.tid=0x0000+d_num;
		//printf("nbns.tid == %d \n",nbns.tid);
		nbns.flags=0x0000;
		nbns.questions=0x0100;
		nbns.answerRRS=0x0000;
		nbns.authorityRRS=0x0000;	
		nbns.additionalRRS=0x0000;
		nbns.name[0]=0x20;nbns.name[1]=0x43;	nbns.name[2]=0x4b;	
		int j=0;
		for(j=3;j<34;j++)
			nbns.name[j]=0x41;
		nbns.name[33]=0x00;	
    		nbns.type=0x2100;		
    		nbns.classe=0x0100;	
		//memset(send_buff,..,sizeof(send_buff));	把send_buff设置为udp包格式
		memcpy(send_buff,&nbns,sizeof(nbns)); 
		
		struct sockaddr_in toAddr; 
		bzero((char*)&toAddr,sizeof(toAddr));
		toAddr.sin_family = AF_INET;
		toAddr.sin_addr.s_addr =Invert_IP(FirstIP+d_num);
		toAddr.sin_port = htons(NBNS_PORT); 

		d_num++;

		int send_num =0;
		//printf("nbns.tid == %d IP == %s\n",nbns.tid,inet_ntoa(toAddr.sin_addr));	
		send_num = sendto(sockfd, send_buff, sizeof(send_buff), 0, (struct sockaddr *)&toAddr, sizeof(toAddr) );
		//if(send_num != sizeof(send_buff))	//sizeof(nbns)=50 ?	
		//{
			//printf("sendto() error\n");
			//close(sockfd);
			//return 0;		
		//}
	}

	while(1)
	{
		fd_set fdset;
		struct timeval timeout={1,0}; //select等待1秒,1秒轮询,要非阻塞就置0
		//         timeout.tv_sec = 1;
       	//         timeout.tv_usec = 0;
		FD_ZERO(&fdset); 			//每次循环都要清空集合,否则不能检测描述符变化
		FD_SET(sockfd,&fdset); 	//添加描述符
		int maxfdp = sockfd+1; 	//描述符最大值加1
		switch(select(maxfdp,&fdset,NULL,NULL,&timeout)) //select使用
		{
			case -1: 
				//printf("[select error!]\n");
				return 0;//select错误,退出程序
			case 0:		//等待超时
				//printf("Host Name: %-30s ","NA");
				//printf("MAC: NA  ");
				//printf(" [time out!]\n");
				return 0; //再次轮询				
			default:
				//unsigned int recv_num = 0;
				//recv_num = 
				recvfrom(sockfd, recv_buff, sizeof(recv_buff), 0,  (struct sockaddr *)NULL, (int*)NULL);
				//if( recv_num < 80 )
				//{
					//printf("recvfrom() too small\n");
					//close(sockfd);
				//	break;			
				//}
				//printf("recvfrom() ok\n");
				unsigned short int temptid=0;
				memcpy(&temptid,recv_buff,2);
				//unsigned  char b1,b2;
				//b1=temptid & 0x00FF;
				//b2=(temptid>> 8) & 0x00FF;
				//temptid = (b1<<8)|b2;
				//printf("temptid == %d \n",temptid);
				unsigned long Temp_IP2 = TempStartIP;
				Temp_IP2+=temptid;
				struct sockaddr_in toAddr; 
				bzero((char*)&toAddr,sizeof(toAddr));
				toAddr.sin_family = AF_INET;
				toAddr.sin_addr.s_addr =Invert_IP(Temp_IP2);
				toAddr.sin_port = htons(NBNS_PORT); 
				//printf("  IP: %-18s",inet_ntoa(toAddr.sin_addr));
				printf(" %-16s",inet_ntoa(toAddr.sin_addr));
				unsigned short int NumberOfNames = 0;
				memcpy(&NumberOfNames,recv_buff+56,1);
				
				int i=0;
				int NUM=(NumberOfNames>2?2:NumberOfNames);
				//printf("Host Name: ");
				for(i=0;i<NUM;i++)//依次读取netbios name	
				{	
					char NetbiosName[16] ={0}; 
					memcpy(NetbiosName,recv_buff+57+i*18,16);	//Segmentation fault
					printf("%-16s",NetbiosName);
					//if(i != NUM-1) 		
					//	printf("/");
				}	
				//printf("MAC: ");
				unsigned short int mac[6]={0};
				for(i=0;i<6;i++)
				{
					memcpy(&mac[i],recv_buff+57+NumberOfNames*18+i,1);
					printf("%02X",mac[i]);
					if(i!=5) 		
						printf("-");
				}
				printf("\n");
		}
		//return 0;
	}
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -