summaryrefslogtreecommitdiffstats
path: root/lanbrowsing/lisa/netscanner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lanbrowsing/lisa/netscanner.cpp')
-rw-r--r--lanbrowsing/lisa/netscanner.cpp663
1 files changed, 663 insertions, 0 deletions
diff --git a/lanbrowsing/lisa/netscanner.cpp b/lanbrowsing/lisa/netscanner.cpp
new file mode 100644
index 00000000..acf0515c
--- /dev/null
+++ b/lanbrowsing/lisa/netscanner.cpp
@@ -0,0 +1,663 @@
+/* netscanner.cpp
+ *
+ * Copyright (c) 2000, Alexander Neundorf,
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the COPYING file.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "config.h"
+#include "netscanner.h"
+#include "ipaddress.h"
+#include "lisadefines.h"
+#include <iostream>
+
+#ifdef LISA_DEBUG
+#undef LISA_DEBUG
+#endif
+#define LISA_DEBUG 0
+
+#ifdef dcerr
+#undef dcerr
+#endif
+
+#ifdef mdcerr
+#undef mdcerr
+#endif
+
+#define dcerr if (LISA_DEBUG==1) std::cerr<<"NetScanner::"
+#define mdcerr if (LISA_DEBUG==1) std::cerr<<procId<<" NetScanner::"
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#ifdef __osf__
+#undef BYTE_ORDER
+#define _OSF_SOURCE
+#undef _MACHINE_ENDIAN_H_
+#undef __STDC__
+#define __STDC__ 0
+#include <netinet/ip.h>
+#undef __STDC__
+#define __STDC__ 1
+#endif
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif
+
+struct ICMPEchoRequest
+{
+ unsigned char type;
+ unsigned char code;
+ unsigned short int checkSum;
+ unsigned short id;
+ unsigned short seqNumber;
+};
+
+unsigned short in_cksum(unsigned short *addr, int len)
+{
+ int nleft = len;
+ int sum(0);
+ unsigned short *w = addr;
+ unsigned short answer = 0;
+
+ /*
+ * Our algorithm is simple, using a 32 bit accumulator (sum), we add
+ * sequential 16 bit words to it, and at the end, fold back all the
+ * carry bits from the top 16 bits into the lower 16 bits.
+ */
+ while (nleft > 1)
+ {
+ sum += *w++;
+ nleft -= 2;
+ }
+
+ /* 4mop up an odd byte, if necessary */
+ if (nleft == 1)
+ {
+ *(unsigned char *)(&answer) = *(unsigned char *)w ;
+ sum += answer;
+ }
+
+ /* 4add back carry outs from top 16 bits to low 16 bits */
+ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
+ sum += (sum >> 16); /* add carry */
+ answer = ~sum; /* truncate to 16 bits */
+ return(answer);
+}
+
+
+NetScanner::NetScanner(int& rawSocketFD, int strictMode)
+:procId("")
+,m_firstWait(5)
+,m_secondWait(15)
+,m_strictMode(strictMode)
+,m_rawSocketFD(rawSocketFD)
+,validator()
+,ipRangeStr(";")
+,m_maxPings(256)
+,m_deliverUnnamedHosts(0)
+,m_useNmblookup(0)
+,hostList(0)
+,tmpIPRange("")
+{}
+
+NetScanner::~NetScanner()
+{
+// std::cerr<<"----------- Netscanner dtor "<<std::endl;
+ delete hostList;
+ ::close(m_rawSocketFD);
+}
+
+void addMissingSemicolon(MyString& text)
+{
+ if (text.isEmpty()) return;
+ if (text[text.length()-1]!=';')
+ text+=';';
+}
+
+void NetScanner::configure(Config& config)
+{
+ //ranges are not allowed in strict mode
+ if (!m_strictMode)
+ {
+ ipRangeStr=stripWhiteSpace(config.getEntry("PingAddresses",""));
+ addMissingSemicolon(ipRangeStr);
+ }
+ MyString pingNames=stripWhiteSpace(config.getEntry("PingNames",""));
+ addMissingSemicolon(pingNames);
+ MyString nextName;
+ int semicolonPos=pingNames.find(';');
+ int hostsAdded(0);
+ while (semicolonPos!=-1)
+ {
+ nextName=pingNames.left(semicolonPos);
+ mdcerr<<"configure(): looking up -"<<nextName<<"-"<<std::endl;
+ //now the name lookup
+ in_addr server_addr;
+ hostent *hp=gethostbyname(nextName.data());
+ if (hp!=0)
+ {
+ if ((m_strictMode) && (hostsAdded>=STRICTMODEMAXHOSTS))
+ break;
+ memcpy(&server_addr, hp->h_addr, sizeof(server_addr));
+ char *ip=inet_ntoa(server_addr);
+ mdcerr<<"configure(): looking up "<<nextName<<" gives -"<<ip<<"-"<<std::endl;
+ ipRangeStr=ipRangeStr+ip+';';
+ hostsAdded++;
+ }
+
+ pingNames=pingNames.mid(semicolonPos+1);
+ semicolonPos=pingNames.find(';');
+ }
+ if ((!ipRangeStr.isEmpty()) && (ipRangeStr[0]==';'))
+ ipRangeStr=ipRangeStr.mid(1);
+ m_deliverUnnamedHosts=config.getEntry("DeliverUnnamedHosts",0);
+ m_useNmblookup=config.getEntry("SearchUsingNmblookup",0);
+ m_maxPings=config.getEntry("MaxPingsAtOnce",256);
+ m_firstWait=config.getEntry("FirstWait",5);
+ m_secondWait=config.getEntry("SecondWait",15);
+ if (m_firstWait<1) m_firstWait=1;
+ if (m_maxPings<8) m_maxPings=8;
+ if (m_maxPings>1024) m_maxPings=1024;
+ //on some systems (Solaris ?) select() doesn't work correctly
+ // if the microseconds are more than 1.000.000
+ if (m_firstWait>99) m_firstWait=99;
+ if (m_secondWait>99) m_secondWait=99;
+ mdcerr<<"configure(): "<<ipRangeStr<<std::endl;
+}
+
+struct in_addr NetScanner::getIPfromArray(unsigned int index)
+{
+ //mdcerr<<std::endl<<"*** start ***"<<std::endl;
+ unsigned int tmpIndex(0),indexLeft(index);
+ resetIPRange();
+ MyString tmp(getNextIPRange());
+// mdcerr<<"NetScanner::getIPFromArray: -"<<tmp<<"-"<<std::endl;
+ while (!tmp.isEmpty())
+ {
+ if (tmp.contains('/'))
+ {
+ //mdcerr<<"net/mask combination detected"<<std::endl;
+ MyString netStr(tmp.left(tmp.find("/")));
+ MyString maskStr(tmp.mid(tmp.find("/")+1));
+ unsigned int mask(IPAddress(maskStr).asInt());
+ unsigned int net(IPAddress(netStr).asInt()&mask);
+ if ((~mask)<indexLeft)
+ {
+ indexLeft=indexLeft-(~mask+1);
+ tmpIndex+=(~mask)+1;
+ //mdcerr<<"i: "<<tmpIndex<<" left: "<<indexLeft<<std::endl;
+ }
+ else
+ {
+ net+=indexLeft;
+ return IPAddress(net).asStruct();
+ //return string2Struct(ipInt2String(net));
+ }
+ }
+ else if (tmp.contains('-')==1)
+ {
+ //mdcerr<<"single range detected"<<std::endl;
+ MyString fromIPStr(tmp.left(tmp.find("-")));
+ MyString toIPStr(tmp.mid(tmp.find("-")+1));
+ //mdcerr<<"fromIPStr: "<<fromIPStr<<std::endl;
+ //mdcerr<<"toIPStr: "<<toIPStr<<std::endl;
+ unsigned int fromIP(IPAddress(fromIPStr).asInt());
+ unsigned int toIP(IPAddress(toIPStr).asInt());
+ //unsigned int fromIP(ipString2Int(fromIPStr)), toIP(ipString2Int(toIPStr));
+ //index hinter diesem bereich
+ if ((fromIP+indexLeft)>toIP)
+ {
+ tmpIndex+=1+toIP-fromIP;
+ indexLeft=indexLeft-(1+toIP-fromIP);
+ //mdcerr<<"i: "<<tmpIndex<<" left: "<<indexLeft<<std::endl;
+ }
+ //index in diesem bereich
+ else
+ {
+ fromIP+=indexLeft;
+ return IPAddress(fromIP).asStruct();
+ //return string2Struct(ipInt2String(fromIP));
+ }
+
+ }
+ else if (tmp.contains('-')==4)
+ {
+ //mdcerr<<"multiple range detected"<<std::endl;
+ int cp(tmp.find('-'));
+ int from1(atoi(tmp.left(cp).data()));
+ tmp=tmp.mid(cp+1);
+
+ cp=tmp.find('.');
+ int to1(atoi(tmp.left(cp).data()));
+ tmp=tmp.mid(cp+1);
+
+ cp=tmp.find('-');
+ int from2(atoi(tmp.left(cp).data()));
+ tmp=tmp.mid(cp+1);
+
+ cp=tmp.find('.');
+ int to2(atoi(tmp.left(cp).data()));
+ tmp=tmp.mid(cp+1);
+
+ cp=tmp.find('-');
+ int from3(atoi(tmp.left(cp).data()));
+ tmp=tmp.mid(cp+1);
+
+ cp=tmp.find('.');
+ int to3(atoi(tmp.left(cp).data()));
+ tmp=tmp.mid(cp+1);
+
+ cp=tmp.find('-');
+ int from4(atoi(tmp.left(cp).data()));
+ tmp=tmp.mid(cp+1);
+
+ int to4(atoi(tmp.data()));
+
+ unsigned int count((1+to4-from4)*(1+to3-from3)*(1+to2-from2)*(1+to1-from1));
+ if (count<indexLeft)
+ {
+ tmpIndex+=count;
+ indexLeft-=count;
+ //mdcerr<<"i: "<<tmpIndex<<" left: "<<indexLeft<<std::endl;
+ }
+ else
+ {
+ for (int b1=from1; b1<=to1; b1++)
+ for (int b2=from2; b2<=to2; b2++)
+ for (int b3=from3; b3<=to3; b3++)
+ for (int b4=from4; b4<=to4; b4++)
+ {
+ if (tmpIndex==index)
+ {
+ return IPAddress(b1,b2,b3,b4).asStruct();
+ };
+ tmpIndex++;
+ indexLeft--;
+ //mdcerr<<"i: "<<tmpIndex<<" left:"<<indexLeft<<std::endl;
+ }
+ }
+ }
+ //single IP address
+ else if (tmp.contains('.')==3)
+ {
+ //mdcerr<<"single IP address detected"<<std::endl;
+ //if (tmpIndex==index) return string2Struct(tmp);
+ if (tmpIndex==index) return IPAddress(tmp).asStruct();
+ else
+ {
+ tmpIndex++;
+ indexLeft--;
+ //mdcerr<<"i: "<<tmpIndex<<" left: "<<indexLeft<<std::endl;
+ }
+ }
+ //mdcerr<<"nextIPRange: *"<<tmp<<"*"<<std::endl;
+ tmp=getNextIPRange();
+ }
+ return IPAddress("0.0.0.0").asStruct();
+}
+
+void NetScanner::resetIPRange()
+{
+ tmpIPRange=ipRangeStr;
+}
+
+MyString NetScanner::getNextIPRange()
+{
+ if (tmpIPRange.contains(';')<1) return "";
+ int cp(tmpIPRange.find(';'));
+ MyString tmp(tmpIPRange.left(cp));
+ tmpIPRange=tmpIPRange.mid(cp+1);
+ return tmp;
+}
+
+char* NetScanner::ip2Name(struct in_addr ip)
+{
+ struct hostent *hostname=0;
+ // Set the hostname of node
+ if ( ( hostname = gethostbyaddr( (char *) &ip.s_addr, 4, AF_INET ) ) == 0 )
+ {
+ mdcerr << "ip2Name gethostbyname* error" << std::endl;
+ return inet_ntoa( ip );
+ }
+ mdcerr<<"ip2name -"<<hostname->h_name<<std::endl;
+ return hostname->h_name;
+}
+
+void NetScanner::nmblookupScan(std::list<Node>* newList)
+{
+ mdcerr<<"nmblookupScan()"<<std::endl;
+ //newList->clear();
+ FILE * nmblookupFile=popen("nmblookup \"*\"","r");
+ //no success
+ if (nmblookupFile==0)
+ {
+ mdcerr<<"nmblookupScan(): could not start nmblookup"<<std::endl;
+ return;
+ };
+ MyString dummy("");
+ char *receiveBuffer=0;
+ int bufferSize(0);
+ int nmblookupFd=fileno(nmblookupFile);
+ struct timeval tv;
+ fd_set fds;
+ int done(0);
+ int timeOuts(0);
+ char *tmpBuf=new char[16*1024];
+ do
+ {
+ 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);
+
+ // Warning: The return value of pclose may be incorrect due to the
+ // SIGCHLD handler that is installed. Ignore it!
+ 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';
+
+ //std::cerr<<receiveBuffer<<std::endl;
+
+ tmpBuf=receiveBuffer;
+ int bytesLeft=bufferSize;
+
+ int bufferState=0;
+ while (bytesLeft>0)
+ {
+ //mdcerr<<"bytesLeft: "<<bytesLeft<<" received: "<<bufferSize<<std::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];
+ //std::cerr<<"tmpBuf: -"<<tmpBuf<<"-"<<std::endl;
+ if (sscanf(tmpBuf,"%s *<00>\n",tmpIP) == 1) {
+ mdcerr<<"nmblookupScan: tmpIP: -"<<tmpIP<<"-"<<std::endl;
+ struct sockaddr_in addr;
+ if ((addr.sin_addr.s_addr = inet_addr(tmpIP)) != INADDR_NONE)
+ if (!hostAlreadyInList(addr.sin_addr.s_addr,newList))
+ {
+ if (validator.isValid(addr.sin_addr.s_addr))
+ {
+ mdcerr<<"nmblookupScan: adding "<<inet_ntoa(addr.sin_addr)<<std::endl;
+ newList->push_back(Node(dummy,addr.sin_addr.s_addr));
+ }
+ }
+ }
+ }
+ tmpBuf=endOfLine+1;
+ };
+ mdcerr<<"nmblookupScan: finished"<<std::endl;
+ delete [] receiveBuffer;
+}
+
+void NetScanner::pingScan(std::list<Node>* newList) //the ping-version
+{
+ mdcerr<<"pingScan()"<<std::endl;
+ //newList->clear();
+ MyString dummy("");
+ mdcerr<<"pingScan: m_maxPings: "<<m_maxPings<<std::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,(char*)&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++)
+ {
+ mdcerr<<"******************** starting loop *****************"<<std::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++;
+// mdcerr<<"pingScan(): trying "<<inet_ntoa(tmpIP)<<std::endl;
+ if (hostAlreadyInList(tmpIP.s_addr,newList))
+ mdcerr<<"already in list :-)"<<std::endl;
+ if (!validator.isValid(tmpIP.s_addr))
+ mdcerr<<"pingScan(): invalid IP :-("<<std::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;
+ (void)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));
+// mdcerr<<"pingScan: pinging "<<inet_ntoa(toAddr.sin_addr)<<std::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);
+ tv1.tv_sec=0;
+ tv1.tv_usec=0;
+ while(select(m_rawSocketFD+1,&sockFDset,0,0,&tv1)>0)
+ {
+ received=recvfrom(m_rawSocketFD, (char*)&receiveBuf, 16*1024, 0,
+ (sockaddr*)&fromAddr, &length);
+ if (received!=-1)
+ {
+// mdcerr<<"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;
+ //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 :-)
+// mdcerr<<"pingScan: adding "<<inet_ntoa(fromAddr.sin_addr)<<std::endl;
+ newList->push_back(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
+ }
+ mdcerr<<"pingScan() ends"<<std::endl;
+}
+
+void NetScanner::doScan()
+{
+ mdcerr<<"doScan"<<std::endl;
+ //child
+ std::list<Node>* tmpPingList=new std::list<Node>;
+ mdcerr<<"doScan: created list"<<std::endl;
+ if (m_useNmblookup)
+ nmblookupScan(tmpPingList);
+ pingScan(tmpPingList);
+ // get the names from cache or lookup
+ completeNames(tmpPingList);
+ mdcerr<<"doScan: completed names"<<std::endl;
+ if (m_deliverUnnamedHosts==0)
+ removeUnnamedHosts(tmpPingList);
+
+ mdcerr<<"doScan: added hosts"<<std::endl;
+
+ delete hostList;
+ hostList=tmpPingList;
+}
+
+int NetScanner::hostAlreadyInList(int ip, std::list<Node>* nodes)
+{
+ for (std::list<Node>::iterator node = nodes->begin(); node != nodes->end(); node++)
+ {
+ if (node->ip==ip)
+ return 1;
+ }
+ return 0;
+}
+
+void NetScanner::removeUnnamedHosts(std::list<Node>* nodes)
+{
+ nodes->remove_if(is_unnamed_node());
+}
+
+void NetScanner::completeNames(std::list<Node>* nodes)
+{
+ struct sockaddr_in tmpAddr;
+ //for every host
+ for (std::list<Node>::iterator node = nodes->begin(); node != nodes->end(); node++)
+ {
+ tmpAddr.sin_addr.s_addr=node->ip;
+ mdcerr<<"completeNames: looking up "<<inet_ntoa(tmpAddr.sin_addr)<<std::endl;
+ int done(0);
+ //first look wether we have the name already
+ if (hostList!=0) for (std::list<Node>::iterator oldNode=hostList->begin(); oldNode!=hostList->end(); oldNode++)
+ {
+ if (node->ip==oldNode->ip)
+ {
+ mdcerr<<"completeNames: cached: "<<oldNode->name<<" :-)"<<std::endl;
+ node->name=oldNode->name;
+ done=1;
+ break;
+ }
+ }
+ //otherwise do a name lookup
+ if (!done)
+ {
+ //IPAddress tmpAddress(node->ip);
+ //mdcerr<<"NetScanner::completeNames: doing actual lookup"<<std::endl;
+ node->name=ip2Name(tmpAddr.sin_addr);
+ mdcerr<<"completeNames: resolved: "<<node->name<<std::endl;
+ }
+ }
+}
+