Beispiel #1
0
static void parseUdpDataHeader(xmlDocPtr doc, xmlNodePtr cur)
{
	cur = cur->xmlChildrenNode;
	while(cur!=NULL){
		if((!xmlStrcmp(cur->name,(const xmlChar *)"udpHeader")))
			parseUdpHeader(doc,cur);
		if((!xmlStrcmp(cur->name,(const xmlChar *)"ipHeader")))
			parseIpHeader(doc,cur,2);
		cur = cur->next;
	}
}
void *udpScan(void *arg) 
{
   args *myarg = (args *)arg;
   int protocolNumber;
   protocolNumber= myarg->protocolNum;
   string destIp = myarg->ip;
   bool isIp4;
   int version = ipVersion(destIp);

   if (version == IPV4 ) 
   {               
           isIp4 = true;
   }
   else if (version == IPV6 ) 
   {    
           isIp4 = false;
   }  
   else if ( version == NO_IP_FORMAT ) 
   {
       cout << "invalid IP"; 
       pthread_exit(NULL); 
   }

   //extract details from the myOpt class
   int numOfScans =  myOpt.getScanOptionLength();
   int sockfd, sockicmpfd;
   //different header class
   buildIpHeader ipPkt;
   buildUdpHeader udpPkt;
   buildIp6Header ip6Pkt;
   struct ps_udphdr *udphdrSend , *udphdrRecv;
   struct ps_iphdr *iphdrSend , *iphdrRecv;
   struct ps_ip6hdr *ip6hdrSend , *ip6hdrRecv;
   struct sockaddr_in srvaddr;
   
   struct hostent *hstent, *servTcpIpAddr;
   struct sockaddr_in clientsin;
   struct servent *serv,*poss_serv;
   struct sockaddr_storage recvStorage;
   struct sockaddr_in6 clientsin6; 
   int IPHEADER ;

   if ( isIp4) 
       IPHEADER = IPHEADER_SIZE;
   else
       IPHEADER = IPV6HEADER_SIZE;
   
   int packetLen = PSEUDOHEADER_SIZE+UDPHEADER_SIZE+IPHEADER;

   unsigned char *packetData = new unsigned char[packetLen];
   struct ps_pseudohdr *pseudohdr;
   struct ps_pseudo6hdr *pseudo6hdr;
   unsigned char segment[UDPHEADER_SIZE+PSEUDOHEADER_SIZE+DATA_SIZE];
   unsigned char recvUdpPacketData[packetLen],recvIcmpPacketData[packetLen];
   int portNumber;

   pthread_mutex_lock(&lockPort);
    	portNumber=  myOpt.getPort(portIndex);
	portIndex++;
   pthread_mutex_unlock(&lockPort);

   if ( portNumber == 0 ) 
   {
     	delete[] packetData;
      	pthread_exit(NULL);
   }  
 
   while( portNumber) 
   {
	if ( protocolNumber != NO_PROTO) 
           cout<<"\nProtocol: "<<protocolNumber<<"\n";
   	setZeroMemory(packetData,packetLen);
        setZeroMemory(segment,TCPHEADER_SIZE+PSEUDOHEADER_SIZE);
        map<string,string> p;

        //Declare socket TCP
        if ( isIp4)
            sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
        else
            sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
             
        if(sockfd < 0 ) 
	{
	     delete[] packetData;
             perror("sockfd create : ");
             pthread_exit(NULL);   
        }

        sockicmpfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
            
        if (sockicmpfd < 0 ) 
	{ 
             perror("socket ICMP connect Error()\n");
             delete[] packetData;
             pthread_exit(NULL);
        }  
        //set UDP header
        udpPkt.setUdpHeader(portNumber);
        udphdrSend = udpPkt.getUdpHeader();
                      
        if ( isIp4 ) 
	{ 
             ipPkt.setIpHeader(myOpt.getSourceIp(),destIp,IPPROTO_UDP);
             iphdrSend = ipPkt.getIpHeader();
             //cout << "IP while sending pkt : = " << inet_ntoa(iphdrSend->ip_src) << " : \n";
             createPseudoHeader(&pseudohdr ,iphdrSend);
             memcpy(segment,(void *)pseudohdr,PSEUDOHEADER_SIZE);
             memcpy(segment+PSEUDOHEADER_SIZE,(void *)udphdrSend,UDPHEADER_SIZE);
             udphdrSend->uh_sum = (CheckSum(segment,UDPHEADER_SIZE+PSEUDOHEADER_SIZE));
             //copy packet
             memcpy(packetData,(void *)iphdrSend, IPHEADER);
             memcpy(packetData+IPHEADER_SIZE,(void *)udphdrSend,UDPHEADER_SIZE);
             free(pseudohdr);           
        }
        else 
	{
             ip6Pkt.setIp6Header(myOpt.getSourceIp(),destIp,IPPROTO_TCP);
             ip6hdrSend = ip6Pkt.getIp6Header();
             createPseudoHeader6(&pseudo6hdr ,ip6hdrSend);
             memcpy(segment,(void *)pseudo6hdr,PSEUDO6HEADER_SIZE);
             memcpy(segment+PSEUDO6HEADER_SIZE,(void *)udphdrSend,UDPHEADER_SIZE);
             udphdrSend->uh_sum = (CheckSum(segment,UDPHEADER_SIZE+PSEUDO6HEADER_SIZE));

	     memcpy(packetData,(void *)ip6hdrSend, IPHEADER);	
             memcpy(packetData+IPHEADER_SIZE,(void *)udphdrSend,UDPHEADER_SIZE);
             free(pseudo6hdr);
	} 
                      
        if ( isIp4) 
	{
            clientsin.sin_family = AF_INET;
            servTcpIpAddr = gethostbyname(destIp.c_str());
            bcopy((char *)servTcpIpAddr->h_addr, (char *)&clientsin.sin_addr.s_addr, servTcpIpAddr->h_length);
            clientsin.sin_port=htons(portNumber);
        }
        else 
	{
            clientsin6.sin6_family = AF_INET6;
            clientsin6.sin6_flowinfo = 0;
            servTcpIpAddr = gethostbyname2(destIp.c_str(),AF_INET6);
            bind(sockfd, ( struct sockaddr *) &clientsin6,sizeof(clientsin6));
            clientsin6.sin6_port=htons(portNumber);
        } 

        int retransStatus= NO_RESPONSE,icmpStatus  = NO_ICMP;
        for(int countRe =0;countRe< NUMBER_RETRANSMISSIONS && (retransStatus == NO_RESPONSE) && ( icmpStatus == NO_ICMP);countRe++)
	{
            const int on = 1;
            int setsockStatus;
            if ( isIp4) {
            	setsockStatus = setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on));
           
            	if (setsockStatus < 0 ) 
	    	{
            	    cerr<< "Cannot set HDRINCL port";
            	    delete[] packetData;
            	    pthread_exit(NULL);
            	}
	    }
            fcntl(sockicmpfd, F_SETFL, O_NONBLOCK);
            fcntl(sockfd, F_SETFL, O_NONBLOCK);
            int sendStatus;
           
            if ( isIp4)
            	sendStatus = sendto(sockfd, packetData, iphdrSend->ip_len, 0, (struct sockaddr *)&clientsin, sizeof(clientsin)) ;
            else 
	    {
            	sendStatus = sendto(sockfd, packetData, ip6hdrSend->ip6_len, 0, (struct sockaddr *)&clientsin6, sizeof(clientsin6)) ;
		
            }
           
            if (sendStatus == -1 && errno != EINTR ) 
	    {
            	//perror(" error in sendto: ");
                delete[] packetData; 
            	pthread_exit(NULL);
            }
            setZeroMemory(recvUdpPacketData,0);
            setZeroMemory(recvIcmpPacketData,0);
            socklen_t fromlen = sizeof (recvStorage);
           
            fd_set fds;
            struct timeval tv;
            FD_ZERO(&fds);
            FD_SET(sockfd, &fds);
            FD_SET(sockicmpfd,&fds);
            tv.tv_sec = TIMEOUT+1;
            tv.tv_usec = 0;
            int selectStatus = select(sockfd+1, &fds, NULL, NULL, &tv);
            int icmpSelectStatus = select(sockicmpfd+1, &fds, NULL, NULL, &tv);        
            int numbytesIcmpRecvd = recvfrom(sockicmpfd,recvIcmpPacketData, packetLen , 0,(struct sockaddr *)&recvStorage, &fromlen);
           
            if ( numbytesIcmpRecvd > 0 ) 
	    {
            	icmpStatus =  parseIcmpHeader(recvIcmpPacketData,numbytesIcmpRecvd,(void *)iphdrSend,version);
            } 
            int numbytesUdpRecvd = recvfrom(sockfd, recvUdpPacketData, packetLen , 0,(struct sockaddr *)&recvStorage, &fromlen);  
            //WHERE
	    //http://linux.die.net/man/2/recvfrom
            if ( numbytesUdpRecvd > 0 ) 
	    {
            	retransStatus = parseUdpHeader(recvUdpPacketData,numbytesUdpRecvd,(void *)iphdrSend,udphdrSend,version);
            }    
   	} //retransmission loop ends , lets check

   	//According to nmap guide:
   	if ( icmpStatus == NO_ICMP) 
   	{
	    p.insert(pair<string,string>("UDP","open|filtered"));
	    int previousPort;
	    previousPort = portNumber;
	    result.insert(pair<int,map<string,string> >(previousPort,p));
	    map<int,map<string,string> >::iterator outerIter;
	    map<string,string>::iterator innerIter;
	    outerIter = result.find(previousPort);
	    cout<<"\nPort:"<<previousPort<<"\n";

	    for(innerIter = outerIter->second.begin(); innerIter!= outerIter->second.end(); innerIter++)
	    {
		cout<<innerIter->first<<"--->"<<innerIter->second<<"\n";	
	    }
	    result.erase(previousPort);
        } 
        else 
        {  
            if ( icmpStatus == ICMP_CLOSE )
	    {
            	//cout << "Closed\n";
	    	p.insert(pair<string,string>("UDP","Closed"));		
	    }
    	    else if (  icmpStatus == ICMP_UNREACHABLE || icmpStatus == ICMP_PROTO_UNREACHABLE)
	    {
            	//cout << "open|filtered\n";
	    	p.insert(pair<string,string>("UDP","open|filtered"));
	    }
      	    else if ( retransStatus == RESPONSE ) // for this case it will not come as we send no payload
	    {
            	//cout << "Udp port is open\n";
	    	p.insert(pair<string,string>("UDP","open"));
	    }
	    int previousPort;
	    previousPort = portNumber;
	    result.insert(pair<int,map<string,string> >(previousPort,p));
	    map<int,map<string,string> >::iterator outerIter;
	    map<string,string>::iterator innerIter;
	    outerIter = result.find(previousPort);
	    cout<<"\nPort:"<<previousPort<<"\n";

	    for(innerIter = outerIter->second.begin(); innerIter!= outerIter->second.end(); innerIter++)
	    {
		cout<<innerIter->first<<"--->"<<innerIter->second<<"\n";	
	    }
	    result.erase(previousPort);
        }
        close(sockfd);
        close(sockicmpfd);           
        pthread_mutex_lock(&lockPort);
        result.insert(pair<int,map<string,string> >(portNumber,p));
        portNumber=  myOpt.getPort(portIndex);
        portIndex++;
        pthread_mutex_unlock(&lockPort);  
   }
   delete[] packetData;
}