From bcb704366cb5e333a626c18c308c7e0448a8e69f Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- lanbrowsing/lisa/netscanner.cpp | 663 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 663 insertions(+) create mode 100644 lanbrowsing/lisa/netscanner.cpp (limited to 'lanbrowsing/lisa/netscanner.cpp') 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, + * neundorf@kde.org + * + * 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 + +#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< +#include +#include +#ifdef __osf__ +#undef BYTE_ORDER +#define _OSF_SOURCE +#undef _MACHINE_ENDIAN_H_ +#undef __STDC__ +#define __STDC__ 0 +#include +#undef __STDC__ +#define __STDC__ 1 +#endif +#include +#include +#include + +#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 "<=STRICTMODEMAXHOSTS)) + break; + memcpy(&server_addr, hp->h_addr, sizeof(server_addr)); + char *ip=inet_ntoa(server_addr); + mdcerr<<"configure(): looking up "<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(): "<toIP) + { + tmpIndex+=1+toIP-fromIP; + indexLeft=indexLeft-(1+toIP-fromIP); + //mdcerr<<"i: "<h_name<h_name; +} + +void NetScanner::nmblookupScan(std::list* newList) +{ + mdcerr<<"nmblookupScan()"<clear(); + FILE * nmblookupFile=popen("nmblookup \"*\"","r"); + //no success + if (nmblookupFile==0) + { + mdcerr<<"nmblookupScan(): could not start nmblookup"<=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<0) + { + //mdcerr<<"bytesLeft: "<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: -"<\n",tmpIP) == 1) { + mdcerr<<"nmblookupScan: tmpIP: -"<push_back(Node(dummy,addr.sin_addr.s_addr)); + } + } + } + } + tmpBuf=endOfLine+1; + }; + mdcerr<<"nmblookupScan: finished"<* newList) //the ping-version +{ + mdcerr<<"pingScan()"<clear(); + MyString dummy(""); + mdcerr<<"pingScan: m_maxPings: "<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; repeatOnce0) + { + received=recvfrom(m_rawSocketFD, (char*)&receiveBuf, 16*1024, 0, + (sockaddr*)&fromAddr, &length); + if (received!=-1) + { +// mdcerr<<"pingScan: received from "<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 "<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"<* tmpPingList=new std::list; + mdcerr<<"doScan: created list"<* nodes) +{ + for (std::list::iterator node = nodes->begin(); node != nodes->end(); node++) + { + if (node->ip==ip) + return 1; + } + return 0; +} + +void NetScanner::removeUnnamedHosts(std::list* nodes) +{ + nodes->remove_if(is_unnamed_node()); +} + +void NetScanner::completeNames(std::list* nodes) +{ + struct sockaddr_in tmpAddr; + //for every host + for (std::list::iterator node = nodes->begin(); node != nodes->end(); node++) + { + tmpAddr.sin_addr.s_addr=node->ip; + mdcerr<<"completeNames: looking up "<::iterator oldNode=hostList->begin(); oldNode!=hostList->end(); oldNode++) + { + if (node->ip==oldNode->ip) + { + mdcerr<<"completeNames: cached: "<name<<" :-)"<name=oldNode->name; + done=1; + break; + } + } + //otherwise do a name lookup + if (!done) + { + //IPAddress tmpAddress(node->ip); + //mdcerr<<"NetScanner::completeNames: doing actual lookup"<name=ip2Name(tmpAddr.sin_addr); + mdcerr<<"completeNames: resolved: "<name<