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; }