| @@ -0,0 +1,33 @@ | ||
| /* cpu.h | ||
| CPS 472 Sample Code | ||
| */ | ||
|
|
||
| #pragma once | ||
| #include <Winternl.h> | ||
| #include <psapi.h> | ||
| #include <math.h> | ||
|
|
||
| #define MAX_CPU 16 | ||
| #define MEGABYTE 1048576 | ||
|
|
||
| class CPU{ | ||
| public: | ||
| int cpus; // # of CPUs | ||
| HMODULE hDll; // handle to the NT dll | ||
| HANDLE hProcess; // handle to the current process | ||
| NTSTATUS (__stdcall *NtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS SystemInformationClass, | ||
| PVOID SystemInformation, | ||
| ULONG SystemInformationLength, | ||
| PULONG ReturnLength); | ||
|
|
||
| SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION info[MAX_CPU]; | ||
| ULONG len; | ||
| __int64 idle[MAX_CPU], kernel [MAX_CPU], user [MAX_CPU]; | ||
|
|
||
| CPU (void); | ||
| ~CPU(); | ||
| double GetCpuUtilization (double*); | ||
| int GetProcessRAMUsage(void); | ||
| int GetSystemRAM (void); | ||
| int GetSystemRAMUsage (void); | ||
| }; |
| @@ -0,0 +1,47 @@ | ||
| /* dns.h | ||
| CPS 472 Sample Code | ||
| */ | ||
|
|
||
| #include "headers.h" | ||
| #include "dns.h" | ||
|
|
||
| // NOTE: link with Iphlpapi.lib; prints primary/second DNS server info | ||
|
|
||
| // dnsIP is assigned the first IP address of local DNS servers after called | ||
| void DNS::printDNSServer(string & dnsIP) | ||
| { | ||
| // MSDN sample code | ||
| FIXED_INFO *FixedInfo; | ||
| ULONG ulOutBufLen; | ||
| DWORD dwRetVal; | ||
| IP_ADDR_STRING * pIPAddr; | ||
|
|
||
| ulOutBufLen = sizeof(FIXED_INFO); | ||
| FixedInfo = (FIXED_INFO *) GlobalAlloc( GPTR, sizeof( FIXED_INFO ) ); | ||
| ulOutBufLen = sizeof( FIXED_INFO ); | ||
|
|
||
| if(ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &ulOutBufLen)) { | ||
| GlobalFree( FixedInfo ); | ||
| FixedInfo = (FIXED_INFO *)GlobalAlloc( GPTR, ulOutBufLen ); | ||
| } | ||
|
|
||
| if ( dwRetVal = GetNetworkParams( FixedInfo, &ulOutBufLen ) ) { | ||
| printf( "Call to GetNetworkParams failed. Return Value: %08x\n", dwRetVal ); | ||
| } | ||
| else { | ||
| printf( "Host Name: %s\n", FixedInfo->HostName ); | ||
| printf( "Domain Name: %s\n", FixedInfo->DomainName ); | ||
|
|
||
| printf( "DNS Servers:\n" ); | ||
| printf( "\t%s\n", FixedInfo->DnsServerList.IpAddress.String); | ||
| dnsIP = FixedInfo->DnsServerList.IpAddress.String; | ||
|
|
||
| pIPAddr = FixedInfo->DnsServerList.Next; | ||
| while ( pIPAddr ) { | ||
| printf( "\t%s\n", pIPAddr ->IpAddress.String); | ||
| pIPAddr = pIPAddr ->Next; | ||
| } | ||
| } | ||
|
|
||
| GlobalFree (FixedInfo); | ||
| } |
| @@ -0,0 +1,11 @@ | ||
| /* dns.h | ||
| CPS 472 Sample Code | ||
| */ | ||
| #pragma once | ||
| #include <Iphlpapi.h> | ||
|
|
||
|
|
||
| class DNS { | ||
| public: | ||
| void printDNSServer (string & dnsIP); | ||
| }; |
| @@ -0,0 +1,11 @@ | ||
| // some .h files every .cpp needs | ||
| #pragma once | ||
| #include <windows.h> | ||
| #include <stdio.h> | ||
| #include <mmsystem.h> | ||
| #include <queue> | ||
| #include <map> | ||
| #include <string> | ||
|
|
||
|
|
||
| using namespace std; // if you're planning to use STL |
| @@ -0,0 +1,68 @@ | ||
| #include "headers.h" | ||
| #include "lookup.h" | ||
| #include <iostream> | ||
|
|
||
| Question::Question(void) // constructor | ||
| { | ||
|
|
||
| }; | ||
|
|
||
| // Packet visual: | ||
| // [ DNS Header - Question Buffer - Query Header ] | ||
| bool Question::MakePacket(char* pkt, FixedDNSheader &dnsheader, QueryHeader &queryheader) | ||
| { | ||
| int size_pkt = strlen(pkt); | ||
| int dhdr_size = sizeof(dnsheader); | ||
| int qhdr_size = sizeof(queryheader); | ||
| int buf_size = sizeof(rawbuffer); | ||
|
|
||
| // add the dns header to pkt | ||
| memcpy(pkt, &dnsheader, dhdr_size); | ||
|
|
||
| // copy the mem from rawbuffer to pkt | ||
| memcpy(pkt + dhdr_size, rawbuffer, buf_size); | ||
|
|
||
| // add the query header to pkt | ||
| //memcpy(pkt + size_pkt - qhdr_size, &queryheader, qhdr_size); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| bool Question::CreateQuestion(string host) | ||
| { | ||
| // only creating the question, so only use size of question | ||
| rawbuffer = new char[host.size() + 2]; | ||
|
|
||
| int position = host.find("."); | ||
| string sub_str; | ||
|
|
||
| int i = 0, sub_size = 0, hdr_size = sizeof(FixedDNSheader); | ||
|
|
||
| // parse the host and place contents in packet | ||
| host += "."; | ||
| while (position != -1) | ||
| { | ||
| sub_size = position - i; | ||
| sub_str = host.substr(i, position); | ||
|
|
||
| rawbuffer[i] = sub_size; // specify the size of the chunk (subdomain) | ||
| i++; | ||
| memcpy(rawbuffer + i, sub_str.c_str(), sub_size); // specify the actual subdomain | ||
|
|
||
| i += sub_size; | ||
| position = host.find(".", i); | ||
| } | ||
| rawbuffer[hdr_size + i] = 0; | ||
|
|
||
| for (int i = 0; i < host.size() + 2; i++) | ||
| { | ||
| std::cout << "i= " << i << " " << rawbuffer[i] << endl; | ||
| } | ||
| getchar(); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| int Question::Size() { | ||
| return sizeof(rawbuffer); | ||
| } |
| @@ -0,0 +1,97 @@ | ||
| /* lookup.h | ||
| CPS 472 Sample Code | ||
| */ | ||
|
|
||
| /* query classes */ | ||
| #define DNS_INET 1 /* the Internet */ | ||
|
|
||
| // Query types are integer numbers specified in RFC 1035. Several useful queries: | ||
|
|
||
| /* DNS query types */ | ||
| #define DNS_A 1 /* name -> IP */ | ||
| #define DNS_NS 2 /* name server */ | ||
| #define DNS_CNAME 5 /* canonical name */ | ||
| #define DNS_PTR 12 /* IP->name */ | ||
| #define DNS_HINFO 13 /* host info */ | ||
| #define DNS_MX 15 /* mail exchange */ | ||
| #define DNS_AXFR 252 /* request for zone transfer */ | ||
| #define DNS_ANY 255 /* all records */ | ||
|
|
||
|
|
||
| /* flags for the DNS header*/ | ||
| #define DNS_QUERY (0 << 15) /* 0 = query; 1 = response */ | ||
| #define DNS_RESPONSE (1 << 15) | ||
|
|
||
| #define DNS_STDQUERY (0) /* opcode - 4 bits */ | ||
| #define DNS_INVQUERY (1 << 11) | ||
| #define DNS_SRVSTATUS (1 << 12) | ||
|
|
||
| #define DNS_AA (1 << 10) /* authoritative answer */ | ||
| #define DNS_TC (1 << 9) /* truncated */ | ||
| #define DNS_RD (1 << 8) /* recursion desired */ | ||
| #define DNS_RA (1 << 7) /* recursion available */ | ||
|
|
||
|
|
||
| /* possible result codes */ | ||
| #define DNS_OK 0 /* rcode = reply codes */ | ||
| #define DNS_FORMAT 1 /* format error (unable to interpret) */ | ||
| #define DNS_SERVERFAIL 2 /* server failure */ | ||
| #define DNS_ERROR 3 /* no DNS entry */ | ||
| #define DNS_NOTIMPL 4 /* not implemented */ | ||
| #define DNS_REFUSED 5 /* server refused the query */ | ||
|
|
||
| // class defines the fixed query header | ||
| /* remember the current packing state */ | ||
| #pragma pack(push) // exact fit data into a structure with given size -- no padding | ||
| #pragma pack(1) | ||
| class QueryHeader{ // 4 bytes | ||
| public: | ||
| u_short type; | ||
| u_short qclass; | ||
| }; | ||
| /* now restore the previous packing state */ | ||
| #pragma pack(pop) | ||
|
|
||
| // Fixed DNS header size: | ||
| #pragma pack(push) // exact fit data into a structure with given size -- no padding | ||
| #pragma pack(1) | ||
| class FixedDNSheader{ // 12 bytes | ||
| public: | ||
| u_short ID; // identification number | ||
|
|
||
| // flags: 2 bytes | ||
| u_short flags; | ||
|
|
||
| u_short questions; // number of question entries | ||
| u_short answers; // number of answer entries | ||
| u_short authRRs; // number of authority entries | ||
| u_short addRRs; // number of resource entries | ||
| }; | ||
| #pragma pack(pop) | ||
|
|
||
|
|
||
| #pragma pack(push) // exact fit data into a structure with given size -- no padding | ||
| #pragma pack(1) // because the struct is 10 bytes | ||
| class FixedRR { // fixed header for RR | ||
| public: | ||
| u_short type; | ||
| u_short RRclass; // | ||
| u_int ttl; // 4 bytes | ||
| u_short len; // the length of the RDATA field | ||
| // RDATA field: a variable length string that describes the resource | ||
| }; | ||
| #pragma pack(pop) | ||
|
|
||
| class Question{ | ||
| public: | ||
| char *rawbuffer; | ||
|
|
||
| Question(void); // constructor | ||
|
|
||
| bool MakePacket(char* pkt, FixedDNSheader &dnsheader, QueryHeader &queryheader); | ||
|
|
||
| bool CreateQuestion(string host); | ||
|
|
||
| int Size(); | ||
|
|
||
| }; |
| @@ -0,0 +1,226 @@ | ||
| /* main.cpp | ||
| CPS 472 Sample Code | ||
| To compile, you need to add additional libraries: | ||
| 1. Right Click on project name, select "Properties" | ||
| 2. Go to Linker/Input/Additional Dependencies: ws2_32.lib;winmm.lib;Iphlpapi.lib;Psapi.lib; | ||
| use ; to separate them. | ||
| */ | ||
|
|
||
| #define _WINSOCK_DEPRECATED_NO_WARNINGS // needed for "inet_add()" function call | ||
|
|
||
| #include "winsock.h" // must include winsock2.h at the very top of the file before include others | ||
| #include "headers.h" | ||
| #include "cpu.h" | ||
| #include "dns.h" | ||
| #include "lookup.h" | ||
|
|
||
| #include <iostream> | ||
|
|
||
|
|
||
|
|
||
| // this class is passed to all threads, acts as shared memory | ||
| class Parameters { | ||
| public: | ||
| HANDLE mutex; | ||
| HANDLE finished; | ||
| HANDLE eventQuit; | ||
| }; | ||
|
|
||
| // this function is where the thread starts | ||
| UINT thread(LPVOID pParam) | ||
| { | ||
| Parameters *p = ((Parameters*)pParam); | ||
|
|
||
| // wait for mutex, then print and sleep inside the critical section | ||
| WaitForSingleObject(p->mutex, INFINITE); // lock mutex | ||
| printf("Thread %d started\n", GetCurrentThreadId()); // always print inside critical section to avoid screen garbage | ||
| Sleep(1000); | ||
| ReleaseMutex(p->mutex); // release critical section | ||
|
|
||
| // signal that this thread has exitted | ||
| ReleaseSemaphore(p->finished, 1, NULL); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| int main(int argc, char* argv[]) | ||
| { | ||
| if (argc != 2) { | ||
| std::printf("Invalid number of args.\n"); | ||
| return -1; | ||
| } | ||
| int arg_type; | ||
| string host = argv[1]; | ||
| if (isdigit(host[0])) { | ||
| std::printf("IP\n"); | ||
| arg_type = 1; | ||
| if (inet_addr(argv[1]) == INADDR_NONE) { | ||
| std::printf("Invalid IP"); | ||
| return -1; | ||
| } | ||
| host = host + ".in-addr.arpa"; | ||
| } | ||
| else { | ||
| std::printf("HOSTNAME\n"); | ||
| arg_type = 2; | ||
| } | ||
| cout << "argc: " << argc << ", argv: " << host << endl; | ||
|
|
||
| WSADATA wsaData; | ||
|
|
||
| // Initialize WinSock in your project only once! | ||
| WORD wVersionRequested = MAKEWORD(2, 2); | ||
| if (WSAStartup(wVersionRequested, &wsaData) != 0) { | ||
| printf("WSAStartup error %d\n", WSAGetLastError()); | ||
| WSACleanup(); | ||
| return -1; | ||
| } | ||
|
|
||
|
|
||
| printf("-----------------\n"); | ||
|
|
||
| // print our primary/secondary DNS IPs | ||
| DNS mydns; | ||
| string dnsIP = ""; | ||
| mydns.printDNSServer(dnsIP); | ||
|
|
||
| printf("-----------------\n"); | ||
|
|
||
| CPU cpu; | ||
| // average CPU utilization over 500 ms; must sleep *after* the constructor of class CPU and between calls to GetCpuUtilization | ||
| Sleep(500); | ||
| // now print | ||
| double util = cpu.GetCpuUtilization(NULL); | ||
| printf("current CPU utilization %f%%\n", util); | ||
|
|
||
| printf("-----------------\n"); | ||
|
|
||
| // thread handles are stored here; they can be used to check status of threads, or kill them | ||
| HANDLE *ptrs = new HANDLE[2]; | ||
| Parameters p; | ||
|
|
||
| // create a mutex for accessing critical sections (including printf) | ||
| p.mutex = CreateMutex(NULL, 0, NULL); | ||
|
|
||
| // create a semaphore that counts the number of active threads | ||
| p.finished = CreateSemaphore(NULL, 0, 2, NULL); | ||
| p.eventQuit = CreateEvent(NULL, true, false, NULL); | ||
|
|
||
| // get current time | ||
| DWORD t = timeGetTime(); | ||
|
|
||
| // structure p is the shared space between the threads | ||
| ptrs[0] = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)thread, &p, 0, NULL); | ||
| ptrs[1] = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)thread, &p, 0, NULL); | ||
|
|
||
| // make sure this thread hangs here until the other two quit; otherwise, the program will terminate prematurely | ||
| WaitForSingleObject(p.finished, INFINITE); | ||
| WaitForSingleObject(p.finished, INFINITE); | ||
|
|
||
|
|
||
| // ------------------------------- testing the DNS query ----------- | ||
|
|
||
| // string host = "www.yahoo.com" ; | ||
| // string host = "7.74.238.131.in-addr.arpa"; | ||
| int pkt_size = sizeof(FixedDNSheader) + sizeof(QueryHeader) + host.size() + 2; //+1 byte for "size" for last substring, +1 for "0" meaning the end of question | ||
|
|
||
| //char* pkt = new char[pkt_size]; | ||
|
|
||
| //FixedDNSheader * dHDR = (FixedDNSheader *)pkt; | ||
| //QueryHeader *qHDR = (QueryHeader*)(pkt + pkt_size - sizeof(QueryHeader)); | ||
|
|
||
| FixedDNSheader * dHDR = new FixedDNSheader; | ||
| QueryHeader * qHDR = new QueryHeader; | ||
|
|
||
| dHDR->ID = htons(102); | ||
| dHDR->questions = htons(1); | ||
| dHDR->addRRs = 0; | ||
| dHDR->answers = 0; | ||
| dHDR->authRRs = 0; | ||
| dHDR->flags = htons(DNS_QUERY | DNS_RD | DNS_STDQUERY); | ||
| // dHDR->flags = htons( 0x0100 ); | ||
|
|
||
| qHDR->qclass = htons(DNS_INET); | ||
| // qHDR->qclass = htons( 0x0001); | ||
|
|
||
| // if hostname | ||
| if (arg_type == 2) { | ||
| qHDR->type = htons(DNS_A); | ||
| } | ||
| // if IP | ||
| else if (arg_type == 1) { | ||
| qHDR->type = htons(DNS_PTR); // for reverse dns lookup | ||
| } | ||
|
|
||
| Question q; | ||
|
|
||
| q.CreateQuestion(host); | ||
|
|
||
| int size = sizeof(FixedDNSheader) + q.Size() + sizeof(QueryHeader); | ||
| char *pkt = new char[size]; | ||
|
|
||
| q.MakePacket(pkt, *dHDR, *qHDR); | ||
|
|
||
| Winsock ws; | ||
|
|
||
| SOCKET sock = ws.OpenSocket(); // defined in winsock.h | ||
|
|
||
| // set up the address of where we're sending data | ||
| struct sockaddr_in send_addr; | ||
| send_addr.sin_family = AF_INET; | ||
| send_addr.sin_addr.S_un.S_addr = inet_addr(dnsIP.c_str()); // 208.67.222.222 | ||
| send_addr.sin_port = htons(53); | ||
|
|
||
| int send_addrSize = sizeof(struct sockaddr_in); | ||
|
|
||
| int sentbytes = sendto(sock, pkt, pkt_size, 0, (struct sockaddr*) &send_addr, send_addrSize); | ||
| cout << "sentbytes=" << sentbytes << endl; | ||
|
|
||
| for (int i = 0; i < pkt_size; i++) | ||
| { | ||
| cout << "i= " << i << " " << pkt[i] << endl; | ||
| } | ||
| cout << endl; | ||
|
|
||
| char recv_buf[512]; | ||
|
|
||
| int recvbytes = 0; | ||
| if (sentbytes > 0) | ||
| recvbytes = recvfrom(sock, recv_buf, 512, 0, (sockaddr *)&send_addr, &send_addrSize); | ||
|
|
||
| cout << "recv_bytes=" << recvbytes << endl; | ||
|
|
||
| FixedDNSheader * rDNS = (FixedDNSheader *)recv_buf; | ||
| cout << "ID=" << ntohs(dHDR->ID) << "??" << ntohs(rDNS->ID) << endl; | ||
| cout << "questions=" << ntohs(rDNS->questions) << endl; | ||
| cout << "Answers=" << ntohs(rDNS->answers) << endl; | ||
| cout << "authRRs=" << ntohs(rDNS->authRRs) << endl; | ||
| cout << "addRRs=" << ntohs(rDNS->addRRs) << endl; | ||
|
|
||
| printf("flag 0x=%x\n", ntohs(rDNS->flags)); | ||
| unsigned short rcode = 0x0F; | ||
| rcode = rcode & ntohs(rDNS->flags); | ||
| rcode = rcode & ntohs(rDNS->flags); | ||
| cout << "Rcode= " << rcode << endl; ; | ||
|
|
||
| // for debugging: | ||
| // for ( int i = 0; i< recvbytes; i++) | ||
| // { | ||
| // printf("%x\t", i, recv_buf[i] ); | ||
| // } | ||
| // cout<<endl; | ||
|
|
||
| closesocket(sock); | ||
|
|
||
| delete[] pkt; | ||
|
|
||
|
|
||
| printf("Terminating main(), completion time %d ms\n", timeGetTime() - t); | ||
|
|
||
| getchar(); | ||
|
|
||
| WSACleanup(); | ||
|
|
||
| return 0; | ||
| } |
| @@ -0,0 +1,236 @@ | ||
| /* main.cpp | ||
| CPS 472 Sample Code | ||
| To compile, you need to add additional libraries: | ||
| 1. Right Click on project name, select "Properties" | ||
| 2. Go to Linker/Input/Additional Dependencies: ws2_32.lib;winmm.lib;Iphlpapi.lib;Psapi.lib; | ||
| use ; to separate them. | ||
| */ | ||
|
|
||
| #define _WINSOCK_DEPRECATED_NO_WARNINGS // needed for "inet_add()" function call | ||
|
|
||
| #include "winsock.h" // must include winsock2.h at the very top of the file before include others | ||
| #include "headers.h" | ||
| #include "cpu.h" | ||
| #include "dns.h" | ||
| #include "lookup.h" | ||
|
|
||
| #include <iostream> | ||
|
|
||
|
|
||
|
|
||
| // this class is passed to all threads, acts as shared memory | ||
| class Parameters{ | ||
| public: | ||
| HANDLE mutex; | ||
| HANDLE finished; | ||
| HANDLE eventQuit; | ||
| }; | ||
|
|
||
| // this function is where the thread starts | ||
| UINT make_thread(LPVOID pParam) | ||
| { | ||
| Parameters *p = ((Parameters*)pParam); | ||
|
|
||
| // wait for mutex, then print and sleep inside the critical section | ||
| WaitForSingleObject(p->mutex, INFINITE); // lock mutex | ||
| printf ("Thread %d started\n", GetCurrentThreadId ()); // always print inside critical section to avoid screen garbage | ||
| Sleep (1000); | ||
| ReleaseMutex(p->mutex); // release critical section | ||
|
|
||
| // signal that this thread has exitted | ||
| ReleaseSemaphore(p->finished, 1, NULL); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| int ref_main(int argc, char* argv[]) | ||
| { | ||
| if (argc != 2) { | ||
| std::printf("Invalid number of args"); | ||
| return -1; | ||
| } | ||
| int arg_type; | ||
| string host = argv[1]; | ||
| if (isdigit(host[0])) { | ||
| std::printf("IP\n"); | ||
| arg_type = 1; | ||
| if (inet_addr(argv[1]) == INADDR_NONE) { | ||
| std::printf("Invalid IP"); | ||
| return -1; | ||
| } | ||
| host = host + ".in-addr.arpa"; | ||
| } | ||
| else { | ||
| std::printf("HOSTNAME\n"); | ||
| arg_type = 2; | ||
| } | ||
| cout << "argc: " << argc << ", argv: " << host << endl; | ||
| WSADATA wsaData; | ||
|
|
||
| getchar(); | ||
|
|
||
| // Initialize WinSock in your project only once! | ||
| WORD wVersionRequested = MAKEWORD(2,2); | ||
| if (WSAStartup(wVersionRequested, &wsaData) != 0) { | ||
| printf("WSAStartup error %d\n", WSAGetLastError ()); | ||
| WSACleanup(); | ||
| return -1; | ||
| } | ||
|
|
||
|
|
||
| printf ("-----------------\n"); | ||
|
|
||
| // print our primary/secondary DNS IPs | ||
| DNS mydns; | ||
| string dnsIP = ""; | ||
| mydns.printDNSServer (dnsIP); | ||
|
|
||
| printf ("-----------------\n"); | ||
|
|
||
| CPU cpu; | ||
| // average CPU utilization over 500 ms; must sleep *after* the constructor of class CPU and between calls to GetCpuUtilization | ||
| Sleep (500); | ||
| // now print | ||
| double util = cpu.GetCpuUtilization (NULL); | ||
| printf ("current CPU utilization %f%%\n", util); | ||
|
|
||
| printf ("-----------------\n"); | ||
|
|
||
| // thread handles are stored here; they can be used to check status of threads, or kill them | ||
| HANDLE *ptrs = new HANDLE [2]; | ||
| Parameters p; | ||
|
|
||
| // create a mutex for accessing critical sections (including printf) | ||
| p.mutex = CreateMutex (NULL, 0, NULL); | ||
|
|
||
| // create a semaphore that counts the number of active threads | ||
| p.finished = CreateSemaphore(NULL, 0, 2, NULL); | ||
| p.eventQuit = CreateEvent (NULL, true, false, NULL); | ||
|
|
||
| // get current time | ||
| DWORD t = timeGetTime(); | ||
|
|
||
| // structure p is the shared space between the threads | ||
| ptrs[0] = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)make_thread, &p, 0, NULL); | ||
| ptrs[1] = CreateThread(NULL, 4096, (LPTHREAD_START_ROUTINE)make_thread, &p, 0, NULL); | ||
|
|
||
| // make sure this thread hangs here until the other two quit; otherwise, the program will terminate prematurely | ||
| WaitForSingleObject(p.finished, INFINITE); | ||
| WaitForSingleObject(p.finished, INFINITE); | ||
|
|
||
| // ---------------------------- testing the DNS query -------- | ||
|
|
||
| // string host = "www.yahoo.com" ; | ||
| // string host = "7.74.238.131.in-addr.arpa"; | ||
| int pkt_size = sizeof(FixedDNSheader) + sizeof(QueryHeader) + host.size() + 2; //+1 byte for "size" for last substring, +1 for "0" meaning the end of question | ||
|
|
||
| char* pkt = new char [pkt_size]; | ||
|
|
||
| FixedDNSheader * dHDR = (FixedDNSheader *) pkt; | ||
| QueryHeader *qHDR = (QueryHeader*) ( pkt+ pkt_size -sizeof (QueryHeader) ); | ||
|
|
||
| dHDR->ID = htons(102); | ||
| dHDR->questions = htons(1); | ||
| dHDR->addRRs = 0; | ||
| dHDR->answers = 0; | ||
| dHDR->authRRs = 0; | ||
| dHDR->flags = htons( DNS_QUERY | DNS_RD | DNS_STDQUERY ); | ||
| // dHDR->flags = htons( 0x0100 ); | ||
|
|
||
| int position = host.find ("."); | ||
| string sub_str; | ||
|
|
||
| int i = 0, sub_size = 0, hdr_size = sizeof(FixedDNSheader); | ||
|
|
||
| host +="." ; | ||
| while ( position != -1 ) | ||
| { | ||
| sub_size = position - i; | ||
| sub_str = host.substr( i, position ); | ||
|
|
||
| pkt[hdr_size + i] = sub_size; // specify the size of the chunk (subdomain) | ||
| i++; | ||
| memcpy ( pkt + hdr_size + i, sub_str.c_str(), sub_size ); // specify the actual subdomain | ||
|
|
||
| i += sub_size; | ||
| position = host.find (".", i ); | ||
| } | ||
| pkt[hdr_size+i]= 0; | ||
|
|
||
| qHDR->qclass = htons(DNS_INET); | ||
| // qHDR->qclass = htons( 0x0001); | ||
|
|
||
| // if hostname | ||
| if (arg_type == 2) { | ||
| qHDR->type = htons(DNS_A); | ||
| } | ||
| // if IP | ||
| else if (arg_type == 1) { | ||
| qHDR->type = htons(DNS_PTR); // for reverse dns lookup | ||
| } | ||
|
|
||
| Winsock ws; | ||
|
|
||
| SOCKET sock = ws.OpenSocket(); // defined in winsock.h | ||
|
|
||
| // set up the address of where we're sending data | ||
| struct sockaddr_in send_addr ; | ||
| send_addr.sin_family = AF_INET; | ||
| send_addr.sin_addr.S_un.S_addr = inet_addr( dnsIP.c_str() ); // 208.67.222.222 | ||
| send_addr.sin_port = htons ( 53 ); | ||
|
|
||
| int send_addrSize= sizeof(struct sockaddr_in); | ||
|
|
||
| int sentbytes = sendto (sock, pkt, pkt_size, 0, (struct sockaddr*) &send_addr, send_addrSize ); | ||
| cout<<"sentbytes=" << sentbytes <<endl; | ||
|
|
||
| for ( int i = 0; i< pkt_size; i++) | ||
| { | ||
| cout << "i= " << i << " " << pkt[i] << endl; | ||
| } | ||
| cout << endl; | ||
|
|
||
| char recv_buf [512]; | ||
|
|
||
| int recvbytes = 0; | ||
| if (sentbytes > 0) | ||
| recvbytes = recvfrom (sock, recv_buf, 512, 0, (sockaddr *)&send_addr, &send_addrSize); | ||
|
|
||
| cout<< "recv_bytes=" << recvbytes <<endl; | ||
|
|
||
| FixedDNSheader * rDNS = (FixedDNSheader *) recv_buf; | ||
| cout << "ID=" << ntohs( dHDR->ID )<< "??" << ntohs( rDNS->ID )<<endl; | ||
| cout << "questions=" << ntohs( rDNS->questions ) <<endl; | ||
| cout << "Answers=" << ntohs( rDNS->answers )<<endl; | ||
| cout << "authRRs="<<ntohs( rDNS->authRRs) <<endl; | ||
| cout << "addRRs=" << ntohs( rDNS->addRRs )<<endl; | ||
|
|
||
| printf ( "flag 0x=%x\n", ntohs( rDNS->flags ) ) ; | ||
| unsigned short rcode = 0x0F; | ||
| rcode = rcode & ntohs( rDNS->flags ); | ||
| rcode = rcode & ntohs( rDNS->flags ); | ||
| cout<<"Rcode= " << rcode <<endl; ; | ||
|
|
||
| // for debugging: | ||
| // for ( int i = 0; i< recvbytes; i++) | ||
| // { | ||
| // printf("%x\t", i, recv_buf[i] ); | ||
| // } | ||
| // cout<<endl; | ||
|
|
||
|
|
||
| closesocket(sock); | ||
|
|
||
| delete[] pkt; | ||
|
|
||
|
|
||
| printf ("Terminating main(), completion time %d ms\n", timeGetTime() - t); | ||
|
|
||
| getchar(); | ||
|
|
||
| WSACleanup(); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
| @@ -0,0 +1,32 @@ | ||
|
|
||
| #include "winsock.h" | ||
|
|
||
|
|
||
| SOCKET Winsock::OpenSocket (void) | ||
| { | ||
| // open a UDP socket | ||
| SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0); //SOCK_DGRAM for UDP sockets | ||
| if(sock == INVALID_SOCKET) | ||
| { | ||
| printf ("socket() generated error %d\n", WSAGetLastError ()); | ||
| WSACleanup (); | ||
| exit (-1); // not graceful, but sufficient for our purposes | ||
| } | ||
|
|
||
| struct sockaddr_in bind_addr; | ||
|
|
||
| // bind to the local address and port 0 | ||
| bind_addr.sin_family = AF_INET; | ||
| bind_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // INADDR_ANY: choose the local address of this computer | ||
| bind_addr.sin_port = htons (0); // 0: let OS select the next available port on which | ||
| // the UDP sock listens for incoming response | ||
|
|
||
| if (bind (sock, (struct sockaddr*) &bind_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) | ||
| { | ||
| printf ("Bind failed with %d\n", WSAGetLastError()); | ||
| exit (-1); | ||
| } | ||
|
|
||
| // then sendto and recvfrom | ||
| return sock; | ||
| } |
| @@ -0,0 +1,18 @@ | ||
| /* winsock.h | ||
| CPS 472 Sample Code | ||
| Define a class that handles socket APIs | ||
| */ | ||
|
|
||
|
|
||
| //#pragma once | ||
| #include <stdio.h> | ||
| #include <winsock2.h> | ||
| #include <time.h> | ||
|
|
||
| class Winsock { | ||
|
|
||
| public: | ||
| SOCKET OpenSocket (void); | ||
|
|
||
| }; |