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

📄 netscanner.cpp

📁 查看局域网的信息,类似网上邻居的功能,例如查看哪台计算机在线等
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   {      FD_ZERO(&fds);      FD_SET(nmblookupFd,&fds);      tv.tv_sec=10;      tv.tv_usec=0;      int result=select(nmblookupFd+1,&fds,0,0,&tv);      //error      if (result<0)         done=1;      //timeout      else if (result==0)      {         timeOuts++;         //3 time outs make 30 seconds, this should be *much* more than enough         if (timeOuts>=3)            done=1;      }      else if (result>0)      {         //read stuff         int bytesRead=::read(nmblookupFd,tmpBuf,16*1024);         //pipe closed         if (bytesRead==0)            done=1;         else         {            char *newBuf=new char[bufferSize+bytesRead];            if (receiveBuffer!=0)            {               memcpy(newBuf,receiveBuffer,bufferSize);               delete [] receiveBuffer;            };            memcpy(newBuf+bufferSize,tmpBuf,bytesRead);            receiveBuffer=newBuf;            bufferSize+=bytesRead;         };      };   } while (!done);   pclose(nmblookupFile);   delete [] tmpBuf;   //we received nothing   if (receiveBuffer==0)      return;   //check for a terrminating '\0'   if (receiveBuffer[bufferSize-1]=='\0')      receiveBuffer[bufferSize-1]='\0';   //cerr<<receiveBuffer<<endl;   tmpBuf=receiveBuffer;   int bytesLeft=bufferSize;   int bufferState=0;   while (bytesLeft>0)   {      //getDebug()<<"bytesLeft: "<<bytesLeft<<" received: "<<bufferSize<<endl;      //since we added a terminating \0 we can be sure here      char *endOfLine=(char*)memchr(tmpBuf,'\n',bytesLeft);      //point to the last character      if (endOfLine==0)         endOfLine=receiveBuffer+bufferSize-1;      //0-terminate the string      *endOfLine='\0';      //now tmpBuf to endOfLine is a 0-terminated string      int strLength=strlen(tmpBuf);      //hmm, if this happens, there must be something really wrong      if (strLength>1000)         break;      bytesLeft=bytesLeft-strLength-1;      if (bufferState==0)      {         if (isdigit(tmpBuf[0]))            bufferState=1;      };      //yes, no else !      if (bufferState==1)      {         char tmpIP[1024];         //cerr<<"tmpBuf: -"<<tmpBuf<<"-"<<endl;         sscanf(tmpBuf,"%s *<00>\n",tmpIP);         getDebug()<<"NetScanner::nmblookupScan: tmpIP: -"<<tmpIP<<"-"<<endl;         struct sockaddr_in addr;         if (inet_aton(tmpIP,&addr.sin_addr))            if  (!hostAlreadyInList(addr.sin_addr.s_addr,newList))            {               if (validator.isValid(addr.sin_addr.s_addr))               {                  getDebug()<<"NetScanner::nmblookupScan: adding "<<inet_ntoa(addr.sin_addr)<<endl;                  newList->append(Node(dummy,addr.sin_addr.s_addr));               };            };      };      tmpBuf=endOfLine+1;   };   getDebug()<<"NetScanner::nmblookupScan: finished"<<endl;   delete [] receiveBuffer;};void NetScanner::pingScan(SimpleList<Node>* newList)   //the ping-version{   getDebug()<<"NetScanner::pingScan()"<<endl;   //newList->clear();   MyString dummy("");   getDebug()<<"NetScanner::pingScan: m_maxPings: "<<m_maxPings<<endl;/*   int bufferSize(60*1024);   getDebug()<<"NetScanner::pingScan: regaining root privileges for setting up the icmp socket"<<endl;   seteuid(0);   int sockFD=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);   getDebug()<<"NetScanner::pingScan: setsockopt returns "<<setsockopt(sockFD,SOL_SOCKET,SO_RCVBUF,&bufferSize,sizeof(bufferSize))<<endl;   //make the socket non-blocking   //long int options = O_NONBLOCK | ::fcntl(sockFD, F_GETFL);   //getDebug()<<"NetScanner::pingScan:: made it non blocking: "<<::fcntl( sockFD, F_SETFL, options )<<endl;   seteuid(getuid());   getDebug()<<"NetScanner::pingScan: dropped root privileges again"<<endl;*/   pid_t pid=getpid();   ICMPEchoRequest echo;   echo.type=ICMP_ECHO;   echo.code=0;   echo.id=pid;   echo.seqNumber=0;   echo.checkSum=0;   echo.checkSum=in_cksum((unsigned short *)&echo,8);   char receiveBuf[16*1024];   //before we start first read everything what might be in the receive buffer   //of the raw socket   timeval tv1;   //wait a moment for answers   tv1.tv_sec = 0;   tv1.tv_usec = 0;   fd_set clearSet;   FD_ZERO(&clearSet);   FD_SET(m_rawSocketFD,&clearSet);   while(select(m_rawSocketFD,&clearSet,0,0,&tv1)>0)   {      ::recvfrom(m_rawSocketFD,&receiveBuf,16*1024,0,0,0);      tv1.tv_sec = 0;      tv1.tv_usec = 0;      FD_ZERO(&clearSet);      FD_SET(m_rawSocketFD,&clearSet);   };   //now the buffer should be empty      //wait a moment for answers   tv1.tv_sec = 0;   tv1.tv_usec = m_firstWait*10*1000;//0.5 sec   int loopCount(2);   if (m_secondWait<0) loopCount=1;   for (int repeatOnce=0; repeatOnce<loopCount; repeatOnce++)   {      getDebug()<<"******************** starting loop *****************"<<endl;      unsigned int current(0);      int finished(0);      while (!finished)      {         for (int con=0; con<m_maxPings; con++)         {            struct in_addr tmpIP;            do            {               tmpIP=getIPfromArray(current);               current++;               getDebug()<<"NetScanner::pingScan(): trying "<<inet_ntoa(tmpIP)<<endl;               if (hostAlreadyInList(tmpIP.s_addr,newList))                  getDebug()<<"already in list :-)"<<endl;               if (!validator.isValid(tmpIP.s_addr))                  getDebug()<<"NetScanner::pingScan(): invalid IP :-("<<endl;               //ping only hosts which are allowed to receive the results               //and which are not in the list            } while ( (tmpIP.s_addr!=0)                      && ((!validator.isValid(tmpIP.s_addr))                      || (hostAlreadyInList(tmpIP.s_addr,newList))));            finished=(tmpIP.s_addr==0);            if (!finished)            {               //send the icmp echo request               struct sockaddr_in toAddr;               toAddr.sin_family = AF_INET;               toAddr.sin_addr = tmpIP;               toAddr.sin_port = 0;               int sb=sendto(m_rawSocketFD,(char*)&echo,sizeof(echo),0,(sockaddr*)&toAddr,sizeof(toAddr));               //int sb=sendto(sockFD,(char*)&echo,sizeof(echo),0,(sockaddr*)&toAddr,sizeof(toAddr));               getDebug()<<"NetScanner::pingScan: pinging "<<inet_ntoa(toAddr.sin_addr)<<endl;            }            else break;         };         select(0,0,0,0,&tv1);         //now read the answers, hopefully         struct sockaddr_in fromAddr;         socklen_t length(sizeof(fromAddr));         int received(0);         fd_set sockFDset;         FD_ZERO(&sockFDset);         FD_SET(m_rawSocketFD,&sockFDset);         //FD_SET(sockFD,&sockFDset);         tv1.tv_sec=0;         tv1.tv_usec=0;         while(select(m_rawSocketFD+1,&sockFDset,0,0,&tv1)>0)         //while(select(sockFD+1,&sockFDset,0,0,&tv1)>0)            //do         {            //getDebug()<<"** recvfrom...";            received=recvfrom(m_rawSocketFD,&receiveBuf,16*1024,0,(sockaddr*)&fromAddr,&length);            //received=recvfrom(sockFD,&receiveBuf,1024,0,(sockaddr*)&fromAddr,&length);            //getDebug()<<" done ****"<<endl;            if (received!=-1)            {               getDebug()<<"NetScanner::pingScan: received from "<<inet_ntoa(fromAddr.sin_addr)<<" "<<received<<" b, ";               struct ip *ipFrame=(ip*)&receiveBuf;               int icmpOffset=(ipFrame->ip_hl)*4;               icmp *recIcmpFrame=(icmp*)(receiveBuf+icmpOffset);               int iType=recIcmpFrame->icmp_type;               //getDebug()<<"icmp type: "<<iType;               //getDebug()<<", icmp id: "<<recIcmpFrame->icmp_id<<endl;               //if its a ICMP echo reply               if ((iType==ICMP_ECHOREPLY)                   //to an echo request we sent                   && (recIcmpFrame->icmp_id==pid)                   //and the host is not yet in the list                   && (!hostAlreadyInList(fromAddr.sin_addr.s_addr,newList)))               {                  //this is an answer to our request :-)                  getDebug()<<"NetScanner::pingScan: adding "<<inet_ntoa(fromAddr.sin_addr)<<endl;                  newList->append(Node(dummy,fromAddr.sin_addr.s_addr));               };            };            tv1.tv_sec=0;            tv1.tv_usec=0;            FD_ZERO(&sockFDset);            FD_SET(m_rawSocketFD,&sockFDset);            //FD_SET(sockFD,&sockFDset);         };      };      tv1.tv_sec = 0;      tv1.tv_usec = m_secondWait*10*1000;//0.5 sec   };   getDebug()<<"NetScanner::pingScan() ends"<<endl;};void NetScanner::doScan(){   getDebug()<<" NetScanner::doScan"<<endl;   //child   SimpleList<Node>* tmpPingList=new SimpleList<Node>;   getDebug()<<" NetScanner::doScan: created list"<<endl;   if (m_useNmblookup)      nmblookupScan(tmpPingList);   pingScan(tmpPingList);   // get the names from cache or lookup   completeNames(tmpPingList);   getDebug()<<"NetScanner::doScan: completed names"<<endl;   if (m_deliverUnnamedHosts==0)      removeUnnamedHosts(tmpPingList);   getDebug()<<"NetScanner::doScan: added hosts"<<endl;      delete hostList;   hostList=tmpPingList;};int NetScanner::hostAlreadyInList(int ip, SimpleList<Node>* nodes){   for (Node* node=nodes->first(); node!=0; node=nodes->next())   {      if (node->ip==ip)         return 1;   };   return 0;};void NetScanner::removeUnnamedHosts(SimpleList<Node>* nodes){   struct in_addr tmpAddr;   Node* pre(0);   for (Node* node=nodes->first(); node!=0; node=nodes->next())   {      //in node this is already in NBO      tmpAddr.s_addr=node->ip;      const char* ip=inet_ntoa(tmpAddr);      //this way we only compare the whole string via strcmp()      //if at least the first char is already the same      if (ip[0]==node->name[0])      {         //this host has no name         if (strcmp(ip,node->name.data())==0)         {            nodes->remove(node);            //set the pointer to the previous item            if (pre==0) node=nodes->first();            else node=pre;         };      };      pre=node;   };};void NetScanner::completeNames(SimpleList<Node>* nodes){   struct sockaddr_in tmpAddr;   //for every host   for (Node* node=nodes->first(); node!=0; node=nodes->next())   {      tmpAddr.sin_addr.s_addr=node->ip;      getDebug()<<"\n NetScanner::completeNames: looking up "<<inet_ntoa(tmpAddr.sin_addr)<<endl;      int done(0);      //first look wether we have the name already      if (hostList!=0) for (Node* oldNode=hostList->first(); oldNode!=0; oldNode=hostList->next())      {         if (node->ip==oldNode->ip)         {            getDebug()<<"NetScanner::completeNames: cached: "<<oldNode->name<<" :-)"<<endl;            node->name=oldNode->name;            done=1;            break;         };      };      //otherwise do a name lookup      if (!done)      {         //IPAddress tmpAddress(node->ip);         //getDebug()<<"NetScanner::completeNames: doing actual lookup"<<endl;         node->name=ip2Name(tmpAddr.sin_addr);         getDebug()<<"NetScanner::completeNames: resolved: "<<node->name<<endl;      };   };};#undef getDebug

⌨️ 快捷键说明

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