📄 netscanner.cpp
字号:
{ 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 + -