www.pudn.com > NETINFO.rar > assemble.cpp
#include#include #include #include #include #include #include #include #include "tools.h" #include "commonDefine.h" #include "collectLine.h" #include "adapList.h" #include "pcap.h" #include "tcpip.h" #include "udp.h" #include "connect.h" #include "lineConnect.h" #include "ToolConnect.h" #include "EmailAnalyse.h" #include "pop3_new.h" #include "smtp_new.h" #include "ftp.h" #include "http.h" #include "acl.h" #include "dns.h" ///////////////////////////////////////////////////////////////////////////////////////// //defines #define HASH_TABLE_SIZE 1001 #define SNAPLEN 1800 #define PCAP_BUFFER_SIZE 4000000 #define PCAP_TIMEOUT_CONTROL 1 #define PCAP_TIMEOUT_CAPTURE 20 #define CHECK_TIMEOUT_INTERVAL 30 ///////////////////////////////////////////////////////////////////////////////////////// //global variables //directory for each protocols char g_szWorkDir[MAX_PATH]; char g_szPop3Dir[MAX_PATH]; char g_szSmtpDir[MAX_PATH]; char g_szFtpDir[MAX_PATH]; char g_szTempDir[MAX_PATH]; char g_szTxtPrintDir[MAX_PATH]; char g_szUdpDir[MAX_PATH]; char g_szHttpDir[MAX_PATH]; char g_szLogFile[MAX_PATH]; //argvs determined variables BOOL g_bControlLAN = FALSE; BOOL g_bFakeDns = FALSE; BOOL g_bUseInputFile = FALSE; BOOL g_bSaveRawContent = FALSE; WORD g_wTcpListenPort = 0; BOOL g_bCaptureUdp = FALSE; WORD g_wUdpListenPort = 0; BOOL g_bOnlyShow = FALSE; BOOL g_bDoNothing = FALSE; BOOL g_bAllConnectionSaved = FALSE; BOOL g_bWriteLogFile = FALSE; //objects pcap_t *g_pInputPcap = NULL; pcap_t *g_pOutputPcap = NULL; pcap_dumper_t *g_pDumpFile = NULL; CMapKeyToConnect* g_hashTbl = NULL; CFtpDataMatchList* g_pFtpDataMatchList = NULL; CPtrList *g_pAcl = NULL; CPtrList *g_pFakeDns = NULL; //synchronous variables BOOL g_bShouldExit = FALSE; DWORD g_dwPcapEnterCount = 0; //check timeout variables time_t g_lastCheckTime = 0; ////////////////////////////////////////////////////////////////////////////////////////// //delete connections that has timeout void CheckConnectionTimeout() { //clearup existing CConnection POSITION pos = g_hashTbl->GetStartPosition(); while( pos!=NULL ) { SOCKET_KEY key; CConnection* pConnect; g_hashTbl->GetNextAssoc(pos, key, pConnect); if( pConnect->IsTimeOut() ) { printf("%d - %d.%d.%d.%d:%d-->%d.%d.%d.%d:%d timeout\n", g_hashTbl->GetCount()-1 , pConnect->m_addr[pConnect->m_connecter].ip.b1, pConnect->m_addr[pConnect->m_connecter].ip.b2, pConnect->m_addr[pConnect->m_connecter].ip.b3, pConnect->m_addr[pConnect->m_connecter].ip.b4, pConnect->m_addr[pConnect->m_connecter].port, pConnect->m_addr[pConnect->m_listener].ip.b1, pConnect->m_addr[pConnect->m_listener].ip.b2, pConnect->m_addr[pConnect->m_listener].ip.b3, pConnect->m_addr[pConnect->m_listener].ip.b4, pConnect->m_addr[pConnect->m_listener].port ); delete pConnect; g_hashTbl->RemoveKey(key); } } } //////////////////////////////////////////////////////////////////////////////////////////// //dispatcher function used by pcap void another_handler(u_char *user, const struct pcap_pkthdr *header, const u_char *pkt_data) { //check if it's time to exit if( g_bShouldExit ) ExitThread(0); g_dwPcapEnterCount++; //copy data to my own buffer for modify BYTE buffer[BUFFER_SIZE]; assert(BUFFER_SIZE >= header->caplen && header->caplen == header->len ); memcpy(buffer, pkt_data, header->caplen); //send the packet to the output network adapter if( g_pOutputPcap ) pcap_sendpacket(g_pOutputPcap, buffer, header->caplen); //save the packet to the dump file if( g_pDumpFile ) pcap_dump((BYTE*)g_pDumpFile, header, pkt_data); //just return when g_bDoNothing is TRUE if( g_bDoNothing ) { g_dwPcapEnterCount--; return; } //analyse packet ETHERNET *ether =(ETHERNET*)buffer; IP *ip = NULL; TCP *tcp = NULL; UDP *udp = NULL; WORD tcpDataLen; BOOL bIsNeatIp = FALSE; if( ether->protocol == ETHER_PROTOCOL_IP ) { ip = (IP*)((BYTE*)ether + sizeof(*ether)); IpNtoh(ip); if( ip->mf ) { //printf("I have found IP packet with fragments!!!\n"); } if( ip->v == 4 && ip->mf == 0 && ip->offset == 0 ) { bIsNeatIp = TRUE; } } //only process non-fragment IP packet if( !bIsNeatIp ) { g_dwPcapEnterCount--; return; } //check connection timeout time_t curTime = time(NULL); if( (DWORD)(curTime - g_lastCheckTime) > CHECK_TIMEOUT_INTERVAL ) { CheckConnectionTimeout(); g_lastCheckTime = time(NULL); } //convert udp from network format to host format if( ip->protocol == IP_PROTOCOL_UDP ) { udp = (UDP*)( (BYTE*)ip + 4 * ip->hl ); UdpNtoh(udp); if( udp->dstPort == PORT_DNS || udp->srcPort == PORT_DNS ) { FAKE_DNS_ENTRY *pEntry = NULL; if( g_bFakeDns && g_pFakeDns && ShouldFakeDns(ip, udp, (BYTE*)(udp+1), g_pFakeDns, &pEntry) ) { BYTE dnsBuffer[65535]; DWORD length; if( MakeFakeDnsReply(ether, ip, udp, (BYTE*)(udp+1), pEntry, dnsBuffer, sizeof(dnsBuffer), &length) ) pcap_sendpacket(g_pInputPcap, dnsBuffer, length); //printf("Fake DNS: %d.%d.%d.%d %s--->%d.%d.%d.%d\n", // ip->src.b1, ip->src.b2, ip->src.b3, ip->src.b4, pEntry->labelList, // pEntry->addrFake.b1, pEntry->addrFake.b2, pEntry->addrFake.b3, pEntry->addrFake.b4 ); } } if( g_bControlLAN ) { //if( UdpShouldDeny(g_pAcl, ip, udp) ) //{ // BYTE icmpBuffer[MAX_TCP_PACKET]; // DWORD length; // if( MakeICMPUnreachablePacket(ether, ip, (BYTE*)pkt_data + sizeof(ETHERNET), ip->hl*4 + 8, icmpBuffer, sizeof(icmpBuffer), &length) ) // pcap_sendpacket(g_pInputPcap, icmpBuffer, length); //} } else if( g_bCaptureUdp ) { if( g_wUdpListenPort == 0 || ( udp->dstPort == g_wUdpListenPort || udp->srcPort == g_wUdpListenPort ) ) ProcessUDP(ip, udp); } g_dwPcapEnterCount--; return; } //convert tcp from network format to host format if( ip->protocol == IP_PROTOCOL_TCP ) { tcp = (TCP*)( (BYTE*)ip + 4 * ip->hl ); TcpNtoh(tcp); tcpDataLen = ip->len - 4 * (ip->hl + tcp->hl); } else { g_dwPcapEnterCount--; return; } //control network according to ACL.TXT if(g_bControlLAN ) { if( TcpShouldDeny(g_pAcl, ip, tcp) ) { BYTE rstBuffer[MAX_TCP_PACKET]; DWORD length; if ( tcp->syn && !tcp->ack ) { if( MakeRstTcpPacket(ether, ip, tcp, FALSE, tcpDataLen, rstBuffer, MAX_TCP_PACKET, &length, TRUE) ) pcap_sendpacket(g_pInputPcap, rstBuffer, length); if( MakeRstTcpPacket(ether, ip, tcp, FALSE, tcpDataLen, rstBuffer, MAX_TCP_PACKET, &length) ) pcap_sendpacket(g_pInputPcap, rstBuffer, length); if( MakeRstTcpPacket(ether, ip, tcp, TRUE, tcpDataLen, rstBuffer, MAX_TCP_PACKET, &length) ) pcap_sendpacket(g_pInputPcap, rstBuffer, length); //if( MakeICMPUnreachablePacket(ether, ip, (BYTE*)pkt_data + sizeof(ETHERNET), ip->hl*4 + 8, rstBuffer, sizeof(rstBuffer), &length) ) // pcap_sendpacket(g_pInputPcap, rstBuffer, length); //printf("%d.%d.%d.%d:%d-->%d.%d.%d.%d:%d denied\n", // ip->src.b1, ip->src.b2, ip->src.b3, ip->src.b4, tcp->srcPort, // ip->dst.b1, ip->dst.b2, ip->dst.b3, ip->dst.b4, tcp->dstPort); g_dwPcapEnterCount--; return; } else if( !tcp->syn && !tcp->rst && !tcp->fin ) { if( MakeRstTcpPacket(ether, ip, tcp, FALSE, tcpDataLen, rstBuffer, MAX_TCP_PACKET, &length) ) pcap_sendpacket(g_pInputPcap, rstBuffer, length); //if( MakeRstTcpPacket(ether, ip, tcp, TRUE, tcpDataLen, rstBuffer, MAX_TCP_PACKET, &length) ) // pcap_sendpacket(g_pInputPcap, rstBuffer, length); //if( MakeRstTcpPacket(ether, ip, tcp, FALSE, tcpDataLen, rstBuffer, MAX_TCP_PACKET, &length, FALSE, TRUE) ) // pcap_sendpacket(g_pInputPcap, rstBuffer, length); //if( MakeRstTcpPacket(ether, ip, tcp, TRUE, tcpDataLen, rstBuffer, MAX_TCP_PACKET, &length, FALSE, TRUE) ) // pcap_sendpacket(g_pInputPcap, rstBuffer, length); //printf("%d.%d.%d.%d:%d-->%d.%d.%d.%d:%d denied\n", // ip->src.b1, ip->src.b2, ip->src.b3, ip->src.b4, tcp->srcPort, // ip->dst.b1, ip->dst.b2, ip->dst.b3, ip->dst.b4, tcp->dstPort); g_dwPcapEnterCount--; return; } } } //calculate key SOCKET_KEY key; TcpIp2TcpAddr(ip, tcp, key.addr); //lookup it in hash table CConnection* pConnect; if( g_hashTbl->Lookup(key, pConnect) ) //already exist { if( !pConnect->OnTcpIpPacket(ip) ) //this connection has been closed { printf("%d - %d.%d.%d.%d:%d-->%d.%d.%d.%d:%d\n", g_hashTbl->GetCount()-1 , pConnect->m_addr[pConnect->m_connecter].ip.b1, pConnect->m_addr[pConnect->m_connecter].ip.b2, pConnect->m_addr[pConnect->m_connecter].ip.b3, pConnect->m_addr[pConnect->m_connecter].ip.b4, pConnect->m_addr[pConnect->m_connecter].port, pConnect->m_addr[pConnect->m_listener].ip.b1, pConnect->m_addr[pConnect->m_listener].ip.b2, pConnect->m_addr[pConnect->m_listener].ip.b3, pConnect->m_addr[pConnect->m_listener].ip.b4, pConnect->m_addr[pConnect->m_listener].port ); delete pConnect; g_hashTbl->RemoveKey(key); } } else //connection not exist before { //a synchronous and ankownledge packet if( tcp->syn && tcp->ack ) { pConnect = NULL; if( g_bControlLAN ) { if( TcpShouldDeny(g_pAcl, ip, tcp) ) { BYTE rstBuffer[MAX_TCP_PACKET]; DWORD length; if( MakeRstTcpPacket(ether, ip, tcp, FALSE, tcpDataLen, rstBuffer, MAX_TCP_PACKET, &length) ) pcap_sendpacket(g_pInputPcap, rstBuffer, length); if( MakeRstTcpPacket(ether, ip, tcp, TRUE, tcpDataLen, rstBuffer, MAX_TCP_PACKET, &length) ) pcap_sendpacket(g_pInputPcap, rstBuffer, length); //printf("%d.%d.%d.%d:%d-->%d.%d.%d.%d:%d denied\n", // ip->dst.b1, ip->dst.b2, ip->dst.b3, ip->dst.b4, tcp->dstPort, // ip->src.b1, ip->src.b2, ip->src.b3, ip->src.b4, tcp->srcPort); } } else if( g_bSaveRawContent ) { if( g_wTcpListenPort == 0 ) pConnect = new CTxtPrintConnection(g_szTxtPrintDir, ip); else { if( tcp->srcPort == g_wTcpListenPort ) pConnect = new CTxtPrintConnection(g_szTxtPrintDir, ip); else pConnect = new CConnection(ip); } } else if( g_bOnlyShow ) { pConnect = new CConnection(ip); } else { CFtpConnection* pFtp = NULL; if( FindMatch(g_pFtpDataMatchList, ip, tcp, &pFtp) ) pConnect = new CFtpDataConnection(pFtp, ip); else if( tcp->srcPort == TCP_PORT_HTTP || tcp->srcPort == 8080 || tcp->srcPort == 3128 ) pConnect = new CHttpConnection(g_szHttpDir, g_szTempDir, ip); else if( tcp->srcPort == TCP_PORT_POP3 ) pConnect = new CPop3Connection(g_szPop3Dir, g_szTempDir, ip); else if( tcp->srcPort == TCP_PORT_SMTP ) pConnect = new CSmtpConnection(g_szSmtpDir, g_szTempDir, ip); else if( tcp->srcPort == TCP_PORT_FTP ) pConnect = new CFtpConnection(g_hashTbl, g_pFtpDataMatchList, g_szFtpDir, ip); else if( g_bAllConnectionSaved ) pConnect = new CTxtPrintConnection(g_szTxtPrintDir, ip); else pConnect = new CConnection(ip); } if( pConnect ) { g_hashTbl->SetAt(key, pConnect); printf("%d + %d.%d.%d.%d:%d-->%d.%d.%d.%d:%d\n", g_hashTbl->GetCount(), pConnect->m_addr[pConnect->m_connecter].ip.b1, pConnect->m_addr[pConnect->m_connecter].ip.b2, pConnect->m_addr[pConnect->m_connecter].ip.b3, pConnect->m_addr[pConnect->m_connecter].ip.b4, pConnect->m_addr[pConnect->m_connecter].port, pConnect->m_addr[pConnect->m_listener].ip.b1, pConnect->m_addr[pConnect->m_listener].ip.b2, pConnect->m_addr[pConnect->m_listener].ip.b3, pConnect->m_addr[pConnect->m_listener].ip.b4, pConnect->m_addr[pConnect->m_listener].port ); } } } g_dwPcapEnterCount--; } //////////////////////////////////////////////////////////////////////////////////////////// //another dispatcher function used by pcap void dispatcher_handler(u_char *user, const struct pcap_pkthdr *header, const u_char *pkt_data) { DWORD i; //copy data to my own buffer for modify BYTE buffer[BUFFER_SIZE]; assert(BUFFER_SIZE >= header->caplen && header->caplen == header->len ); memcpy(buffer, pkt_data, header->caplen); ETHERNET *ether =(ETHERNET*)buffer; IP *ip = NULL; TCP *tcp = NULL; BOOL bIsNeatIpTcp = FALSE; if( ether->protocol == ETHER_PROTOCOL_IP ) { ip = (IP*)((BYTE*)ether + sizeof(*ether)); if( ip->v = 4 && ip->protocol == IP_PROTOCOL_TCP ) { tcp = (TCP*)( (BYTE*)ip + 4 * ip->hl ); bIsNeatIpTcp = TRUE; } } //only process TCP packet if( !bIsNeatIpTcp ) return; //print pkt timestamp and pkt len printf("\n\n\n\n%ld:%ld (%ld:%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->caplen, header->len); //print ethernet header printf("\n[Ethernet header]"); PrintHexByte(stdout, (const BYTE*)ether, sizeof(*ether), MAX_LINE); printf("\nsource address = "); for(i=0; i src[i])); printf("\ndestin address = "); for(i=0; i dst[i])); printf("\nprotocol = %hu", ether->protocol); //process ip header if( ether->protocol == ETHER_PROTOCOL_IP ) { printf("\n\n[ip header]"); printf("\nsizeof(ip)=%d", sizeof(IP) ); PrintHexByte(stdout, (const BYTE*)ip, sizeof(*ip), MAX_LINE); //convert net int and short to local machine IP *ip = (IP*)((BYTE*)ether + sizeof(*ether)); IpNtoh(ip); //print ip header printf("\nVersion = %u, headerlen = %u", (DWORD)(ip->v), (DWORD)(ip->hl) ); printf("\ntos = %02X, len = %u, id = %u", (DWORD)(ip->tos), (DWORD)(ip->len), (DWORD)(ip->id) ); printf("\ndf = %u, mf = %u, offset = %u", (DWORD)(ip->df), (DWORD)(ip->mf), (DWORD)(ip->offset) ); printf("\nttl = %u, protocol = %u, checksum = %u(%04X)", (DWORD)(ip->ttl), (DWORD)(ip->protocol), (DWORD)(ip->checksum), (DWORD)(ip->checksum)); printf("\n%u.%u.%u.%u --> %u.%u.%u.%u", ip->src.b1, ip->src.b2, ip->src.b3, ip->src.b4, ip->dst.b1, ip->dst.b2, ip->dst.b3, ip->dst.b4 ); if( ip->protocol == IP_PROTOCOL_TCP ) { printf("\n\n[tcp header]"); printf("\nsizeof(tcp)=%d", sizeof(TCP) ); PrintHexByte(stdout, (const BYTE*)tcp, sizeof(*tcp), MAX_LINE); //convert net int and short to local machine TCP *tcp = (TCP*)( (BYTE*)ip + 4 * ip->hl ); TcpNtoh(tcp); //print tcp header printf("\nsrcPort = %u, dstPort = %u", tcp->srcPort, tcp->dstPort); printf("\nseqNum = %u, ackNum = %u", tcp->seqNum, tcp->ackNum); printf("\nheadLen = %u, urg = %u, ack = %u, psh = %u, rst = %u, syn = %u, fin = %u", tcp->hl, tcp->urg, tcp->ack, tcp->psh, tcp->rst, tcp->syn, tcp->fin); printf("\nwindow = %u, checksum = %u, urgPointer = %u", tcp->window, tcp->checksum, tcp->urgPoint); //print tcp data printf("\n\n[tcp data]"); if( ip->mf == 0 && ip->offset == 0 ) { DWORD headLen = ip->hl * 4 + tcp->hl * 4; DWORD dataLen = ip->len - headLen; BYTE *pData = (BYTE*)ip + headLen; if( dataLen ) { printf("\ndataLen = %lu", dataLen); PrintHexByte(stdout, pData, dataLen, MAX_LINE); for(i = 0; !iscntrl(pData[i]) && i =0; i--)NULL; i++; memcpy(g_szWorkDir, argv[0], i); g_szWorkDir[i] = 0; sprintf(g_szPop3Dir, "%sPOP3\\", g_szWorkDir); CreateDirectory(g_szPop3Dir, NULL); sprintf(g_szSmtpDir, "%sSMTP\\", g_szWorkDir); CreateDirectory(g_szSmtpDir, NULL); sprintf(g_szFtpDir, "%sFTP\\", g_szWorkDir); CreateDirectory(g_szFtpDir, NULL); sprintf(g_szTempDir, "%sTEMP\\", g_szWorkDir); CreateDirectory(g_szTempDir, NULL); sprintf(g_szTxtPrintDir, "%sTEXT\\", g_szWorkDir); CreateDirectory(g_szTxtPrintDir, NULL); sprintf(g_szUdpDir, "%sUDP\\", g_szWorkDir); CreateDirectory(g_szUdpDir, NULL); sprintf(g_szHttpDir, "%sHTTP\\", g_szWorkDir); CreateDirectory(g_szHttpDir, NULL); sprintf(g_szLogFile, "%sfilelist.txt", g_szWorkDir); } DWORD WINAPI PcapLoopThread( LPVOID lpParameter ) { pcap_loop((struct pcap*)lpParameter, 0, another_handler, NULL); return 0; } void PrintUsage() { char error[PCAP_ERRBUF_SIZE]; printf("\nUsage:\n"); printf(" c.exe [-c [aclFile]] | [-t [TCPport]] [-u [UDPPort]] | [-s] [-i] [-a]\n"); printf(" [-d fakeDnsListFile] [-L]\n"); printf(" <-n input_adapter | -r input_filename>\n"); printf(" [-o output_adapter] [-w output_file] [-p packet_filter_string]\n\n"); printf("-c option means control this LAN by using ACL.TXT or aclFile if aclFile \n"); printf(" parameter exists, and only can be combined with -n\n"); printf("-t option means write raw TCP content to file in text(dir) for learn or debug,\n"); printf(" if TCPport is specified, only the content of connection of port \n"); printf(" will be wrote\n"); printf("-u option means capture all UDP datagrams, writing to files in udp(dir)\n"); printf(" if UDPPort is specified, only UDP of UDPport will be captured\n"); printf("-s option means only show connections, not write to file\n"); printf("-i option means idle( do nothing ), it's used with -r -o -w -p option\n"); printf("-a option means all connections not treated are saved to file in text(dir) \n"); printf("-d means sending fake dns replies as dns server\n"); printf("-L option means write to log file filelist.txt when a file is completely received\n"); printf("-n means get packet from a network adapter\n"); printf("-r means get packet from a file created by a pcap program\n"); printf("-o means write packet to a network adapter\n"); printf("-w means write packet to output_filename\n"); printf("-p applies packet_fileter to winpcap, it must be a quoted string\n\n"); printf("installed adapters:"); PrintAdapter( pcap_lookupdev(error) ); } void main(int argc, char **argv) { DWORD dwInputAdapter = -1; DWORD dwOutputAdapter = -1; char *szInputFile = NULL; char *szOutputFile = NULL; char *szFilter = NULL; char *szAclFile = "acl.txt"; char *szDnsFile = NULL; char error[PCAP_ERRBUF_SIZE]; int i=1; while(i = GetAdapterCount(pcap_lookupdev(error)) ) { printf("adapter is out of range\n"); PrintUsage(); return; } else if ( (g_pInputPcap= pcap_open_live((char*)GetAdapter(pcap_lookupdev(error), dwInputAdapter), SNAPLEN, 1, timeout, error) ) == NULL) { fprintf(stderr,"\nError opening adapter\n"); return; } pcap_setbuff(g_pInputPcap, PCAP_BUFFER_SIZE); } else if( szInputFile ) //input is pcap dump file { if( g_bControlLAN ) { printf("-f parameter cannot be combined with -c option\n"); PrintUsage(); return; } if( !ExistFile(szInputFile) ) { fprintf(stderr,"\ndump file %s doesn't exist\n", szInputFile); return; } if( (g_pInputPcap = pcap_open_offline(szInputFile, NULL)) == NULL) { fprintf(stderr,"\nError opening dump file %s\n", szInputFile); return; } g_bUseInputFile = TRUE; } else { PrintUsage(); return; } //open output network if( dwOutputAdapter != -1 ) { if( dwOutputAdapter >= GetAdapterCount(pcap_lookupdev(error)) ) { printf("output adapter is out of range\n"); PrintUsage(); return; } else if ( (g_pOutputPcap= pcap_open_live((char*)GetAdapter(pcap_lookupdev(error), dwOutputAdapter), SNAPLEN, 1, PCAP_TIMEOUT_CAPTURE, error) ) == NULL) { fprintf(stderr,"\nError opening output adapter\n"); return; } pcap_setbuff(g_pOutputPcap, PCAP_BUFFER_SIZE); } //set input pcap filter struct bpf_program fcode; if(szFilter!=NULL) { //obtain the subnet and netmask bpf_u_int32 subNet,netMask; if( dwInputAdapter!=-1 ) { char deviceName[MAX_PATH]; strcpy(deviceName, (char*)GetAdapter(pcap_lookupdev(error), dwInputAdapter)); char *device = deviceName; if(pcap_lookupnet(device, &subNet, &netMask, error)==-1) { //fprintf(stderr,"\nUnable to obtain the netmask because:\n %s\n", error); netMask = 0xffffff; //c class network mask } } else netMask = 0xffffff;//c class network mask //compile the filter if(pcap_compile(g_pInputPcap, &fcode, szFilter, 1, netMask)<0) { fprintf(stderr,"\nError compiling filter: wrong syntax.\n"); return; } //set the filter if(pcap_setfilter(g_pInputPcap, &fcode)<0) { fprintf(stderr,"\nError setting the filter\n"); return; } } //open the dump file if (szOutputFile != NULL) { g_pDumpFile=pcap_dump_open(g_pInputPcap, szOutputFile); if(g_pDumpFile==NULL) { fprintf(stderr,"\nError opening output file\n"); return; } } //initialize SetConsoleTitle("powerful content capture, press to quit"); PrepareDirectory(argc, argv); g_hashTbl = new CMapKeyToConnect(100); g_hashTbl->InitHashTable(HASH_TABLE_SIZE); g_pFtpDataMatchList = new CFtpDataMatchList; if( g_bControlLAN ) { //load acl char aclFile[MAX_PATH]; sprintf(aclFile, "%s%s", g_szWorkDir, szAclFile); g_pAcl = new CPtrList(); LoadAcl(aclFile, g_pAcl); } if( g_bFakeDns ) { char dnsFile[MAX_PATH]; sprintf(dnsFile, "%s%s", g_szWorkDir, szDnsFile); g_pFakeDns = new CPtrList(); LoadDnsFakeList(dnsFile, g_pFakeDns); } srand(time(NULL)); //start pcap thread DWORD threadId; HANDLE hThread = CreateThread(NULL, 0, PcapLoopThread, g_pInputPcap, 0, &threadId); //loop run to check quit key 'Q' while( 1 ) { DWORD dwExitCode; if( GetExitCodeThread(hThread, &dwExitCode) && dwExitCode != STILL_ACTIVE ) { break; } else if( kbhit() ) { if( toupper( getch() )== 'Q' ) break; } else Sleep(100); } //quit printf("Exiting......\n"); g_bShouldExit = TRUE; while( WaitForSingleObject(hThread, 0)==WAIT_TIMEOUT && g_dwPcapEnterCount!=0 )NULL; TerminateThread(hThread, 0); CloseHandle(hThread); //close pcap handle and pcap_dump handle if( g_pInputPcap ) { pcap_close(g_pInputPcap); g_pInputPcap = NULL; } if( g_pOutputPcap ) { pcap_close(g_pOutputPcap); g_pOutputPcap = NULL; } if( g_pDumpFile ) { pcap_dump_close(g_pDumpFile); g_pDumpFile = NULL; } //clearup acl list if( g_pAcl ) { ClearAcl(g_pAcl); delete g_pAcl; } //clearup dns list if( g_pFakeDns ) { ClearFakeDnsList(g_pFakeDns); delete g_pFakeDns; } //clearup existing CConnection POSITION pos = g_hashTbl->GetStartPosition(); while( pos!=NULL ) { SOCKET_KEY key; CConnection* pConnect; g_hashTbl->GetNextAssoc(pos, key, pConnect); printf("%d - %d.%d.%d.%d:%d-->%d.%d.%d.%d:%d\n", g_hashTbl->GetCount()-1 , pConnect->m_addr[pConnect->m_connecter].ip.b1, pConnect->m_addr[pConnect->m_connecter].ip.b2, pConnect->m_addr[pConnect->m_connecter].ip.b3, pConnect->m_addr[pConnect->m_connecter].ip.b4, pConnect->m_addr[pConnect->m_connecter].port, pConnect->m_addr[pConnect->m_listener].ip.b1, pConnect->m_addr[pConnect->m_listener].ip.b2, pConnect->m_addr[pConnect->m_listener].ip.b3, pConnect->m_addr[pConnect->m_listener].ip.b4, pConnect->m_addr[pConnect->m_listener].port ); delete pConnect; g_hashTbl->RemoveKey(key); } g_hashTbl->RemoveAll(); delete g_hashTbl; delete g_pFtpDataMatchList; }