最近在學習網路過濾這方面,發現在網路上有好多程式表面上寫著過濾功能,但實際並不能對網路資料過濾。我第一步是想寫一個簡單程式來阻止電腦連網,經過網上尋找和MSDN的協助,組成了如下的代碼,按理說是能達到目的的,但運行後還是可以開網頁,看視訊交談等,似乎沒有受到絲毫影響,確實找不出原因。不知道是哪裡不對。
1 #include <iostream.h> 2 #include <stdio.h> 3 #include <winsock2.h> 4 #include <Iphlpapi.h> 5 #include <Fltdefs.h> 6 #pragma comment(lib,"ws2_32") 7 #pragma comment(lib,"Iphlpapi.lib")//.lib尾碼名可以不要 8 9 int main() 10 { 11 //*******************************這一部分主要獲得網卡裝置資訊******************************/ 12 PIP_ADAPTER_INFO pAdapterInfo; 13 PIP_ADAPTER_INFO pAdapter=NULL; 14 DWORD dwRetVal=0; 15 pAdapterInfo=(IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO)); 16 ULONG ulOutBufLen=sizeof(IP_ADAPTER_INFO); 17 18 if(GetAdaptersInfo(pAdapterInfo,&ulOutBufLen)!=ERROR_SUCCESS) 19 { 20 GlobalFree(pAdapterInfo); 21 pAdapterInfo=(IP_ADAPTER_INFO*)malloc(ulOutBufLen); 22 } 23 if((dwRetVal=GetAdaptersInfo(pAdapterInfo,&ulOutBufLen))==NO_ERROR) 24 { 25 pAdapter=pAdapterInfo; 26 while(pAdapter) 27 { 28 printf("------------------------------------------------------------\n"); 29 printf("AdapterName:\t%s\n",pAdapter->AdapterName); 30 printf("AdapterDesc:\t%s\n",pAdapter->Description); 31 printf("AdapterAddr:\t"); 32 for(UINT i=0; i<pAdapter->AddressLength; i++) 33 { 34 printf("%02X%c",pAdapter->Address[i], 35 i==pAdapter->AddressLength-1?'\n':'-'); 36 } 37 printf("AdapterType:\t%d\n",pAdapter->Type); 38 printf("IPAddress:\t%s\n",pAdapter->IpAddressList.IpAddress.String); 39 printf("IPMask:\t\t%s\n",pAdapter->IpAddressList.IpMask.String); 40 41 pAdapter=pAdapter->Next; 42 } 43 } 44 else 45 { 46 printf("Call to GetAdaptersInfo failed \n"); 47 } 48 //***************************************************************************************************************************/ 49 50 //***************************************************************************************************************************/ 51 int result,_ifor,inum;//inum表示要選擇的裝置號,_ifor僅用於下面的for迴圈
52 PBYTE lIp; //儲存本地IP的 53 cout<<"請輸入要選擇的裝置號,從1開始順序往下:"; 54 cin>>inum; 55 56 PIP_ADAPTER_INFO SelectedAdapter; //從這裡提取本地IP地址 57 58 // FILTER_HANDLE fHandle; 只有一個過濾規則,可以不要這個過濾控制代碼 59 INTERFACE_HANDLE hInterface = NULL; 60 result = PfCreateInterface(0,PF_ACTION_FORWARD,PF_ACTION_FORWARD,FALSE,TRUE,&hInterface);//建立一個Filter Interface 61 if(result!=NO_ERROR) 62 { 63 cout<<"Fail to call PfCreateInterface"<<endl; 64 return -1; 65 } 66 67 //邦定過濾介面到本地IP 68 IP_ADDR_STRING *localIp; 69 for(SelectedAdapter=pAdapterInfo,_ifor=1;SelectedAdapter != NULL;SelectedAdapter=SelectedAdapter->Next,_ifor++) 70 { 71 if(_ifor==inum) 72 { 73 // each ip of a adapter,一個適配器可能有多個IP地址 74 for(localIp=&SelectedAdapter->IpAddressList;localIp!=NULL;localIp=localIp->Next) 75 { 76 lIp = (PBYTE)&localIp->IpAddress.String; 77 //cout<<"lIp: "<<lIp<<endl; //有輸出則擷取本地IP成功,發布時去掉該語句 78 PfBindInterfaceToIPAddress(hInterface, PF_IPV4, lIp);//綁定Filter Interface到本地IP 79 } 80 cout<<"lIp: "<<lIp<<endl; 81 break; 82 } 83 } 84 85 //**********************建立過濾規則,填充過濾包的規則結構*********************************/ 86 PF_FILTER_DESCRIPTOR ipFlt; 87 ipFlt.dwFilterFlags = FD_FLAGS_NOSYN; //一直添這個值 88 ipFlt.dwRule = 0; //一直添這個值 89 ipFlt.pfatType = PF_IPV4; //用 ipV4 地址 90 91 ipFlt.SrcAddr = lIp; //設定本地IP地址 92 ipFlt.SrcMask = (PBYTE)SelectedAdapter->IpAddressList.IpMask.String;//本地子網路遮罩 93 ipFlt.wSrcPort = FILTER_TCPUDP_PORT_ANY; //任意來源連接埠 94 ipFlt.wSrcPortHighRange = FILTER_TCPUDP_PORT_ANY; 95 96 ipFlt.DstAddr = 0; //任意目標地址 97 ipFlt.DstMask = 0; 98 ipFlt.wDstPort = FILTER_TCPUDP_PORT_ANY; //任意目標連接埠 99 ipFlt.wDstPortHighRange = FILTER_TCPUDP_PORT_ANY;100 ipFlt.fLateBound = 0;101 102 ipFlt.dwProtocol = FILTER_PROTO_ANY; // 過濾的協議,可選FILTER_PROTO_ICMP103 //*******************************************************************************************/104 105 result = PfAddFiltersToInterface(hInterface, 1, &ipFlt, 0, NULL, NULL);//添加過濾規則到介面106 if(result!=NO_ERROR)107 {108 cout<<"Fail to call PfAddFiltersToInterface"<<endl;109 return -1;110 } 111 result = PfRemoveFilterHandles(hInterface, 1, NULL); //remove filter112 if(result!=NO_ERROR)113 {114 cout<<"Fail to call PfRemoveFiltersHandles"<<endl;115 return -1;116 }117 PfUnBindInterface(hInterface);118 PfDeleteInterface(hInterface);119 return 0;120 }
運行如下
也就是105行的添加過濾規則失敗。若將這行的傳入參數1改為0便沒有這個失敗,但沒有道理啊,也不能實現阻止連網的目的。
整個結構簡單,在VC6.0中編寫的。運行此程式還需要在網上下Iphlpapi.h和fltdefs.h這兩個標頭檔加Iphlpapi.lib這個庫,因為這幾個VC6.0預設安裝後的檔案中是沒有的。