一个简单的嗅探器

来源:互联网 发布:网络电视找不到电视猫 编辑:程序博客网 时间:2024/05/18 04:54
#include <cstdio>#include <iostream>#include <cstring>#include <winsock2.h>#include <mstcpip.h>#include <Windows.h>using namespace std;#define STATUS_FAILED 0xFFFF //异常出错代码#define MAX_PACK_LEN 65535#define MAX_ADDR_LEN 16#define MAX_PROTO_TEXT_LEN 16#define MAX_PROTO_NUM 12#define MAX_HOSTNAME_LEN 255#define CMD_PARAM_HELP true#pragma comment (lib,"Ws2_32.lib")typedef struct _iphead{  unsigned char headLenIpVersion;  unsigned char serviceType;  unsigned short totalLength;  unsigned short ident;  unsigned short frag_and_flags;  unsigned char ttl;  unsigned char protocal;  unsigned short checksum;  unsigned int   sourceIp;  unsigned int   destIp;}IPHEAD,*pIPHEAD;typedef struct _tcphead{USHORT sourcePort;USHORT destPort;UINT    seqNum;UINT    ackNum;UCHAR  headLen_reserve;UCHAR  reserve_flag;USHORT winLen;USHORT checkSum;USHORT mergencyPointer;}TCPHEAD,pTCPHEAD;typedef struct _udphead{   USHORT sourcePort;   USHORT destPort;   USHORT totalLen;   USHORT checkSum;}UDPHEAD,pUDPHEAD;typedef struct _icmp{   BYTE   type;   BYTE   code;   USHORT checkSum;   USHORT id;   USHORT seq;   ULONG  timeStamp;}ICMPHEAD,pICMPHEAD;typedef struct _ProtoMap{  int num;  char protoname[MAX_PROTO_TEXT_LEN];}PROTOMAP;PROTOMAP protoMap[MAX_PROTO_NUM]={{IPPROTO_IP,"IP"},{IPPROTO_ICMP,"ICMP"},{IPPROTO_IGMP,"IGMP"},{IPPROTO_GGP,"GGP"},{IPPROTO_TCP,"TCP"},{IPPROTO_PUP,"PUP"},{IPPROTO_UDP,"UDP"},{IPPROTO_IDP,"IDP"},{IPPROTO_ND,"ND"},{IPPROTO_RAW,"RAW"},{IPPROTO_MAX,"MAX"},{NULL,""}};SOCKET SockRaw;char tcpFlag[6]={'F','S','R','P','A','U'};//TCP标志位bool ParamTcp=false; //关注TCPbool ParamUdp=false;//关注UDPbool ParamIcmp=false;//关注ICMPbool ParamDecode=true;char *strFromIpFilter=NULL;char *strDestIpFilter=NULL;int DecodeIpPack(char *,int );int DecodeTcpPack(char *);int DecodeUdpPack(char *);int DecodeIcmpPack(char *);void CheckSockError(int,char * );char * CheckProtocol(int);void usage(void);bool GetCmdLine(int,char **);int main(int argc,char **argv){ printf("%d %s %s %s %s\n",argc,argv[0],argv[1],argv[2],argv[3]); int iErrorCode; char RecvBuf[MAX_PACK_LEN]={0}; usage(); if(GetCmdLine(argc,argv)==CMD_PARAM_HELP) exit(0);  WSADATA wsaData; iErrorCode=WSAStartup(MAKEWORD(2,2),&wsaData);  CheckSockError(iErrorCode,"WSAStartup"); SockRaw=socket(AF_INET,SOCK_RAW,IPPROTO_IP); CheckSockError(SockRaw,"socket"); //Get the ip address of my host char FAR name[MAX_HOSTNAME_LEN]; iErrorCode=gethostname(name,MAX_HOSTNAME_LEN); CheckSockError(iErrorCode,"gethostname"); struct hostent FAR *pHostent; pHostent=(struct hostent *)malloc(sizeof(struct hostent)); pHostent=(struct hostent *)gethostbyname(name); SOCKADDR_IN sa; sa.sin_family=AF_INET; sa.sin_port=htons(6000); memcpy(&sa.sin_addr.S_un.S_addr,pHostent->h_addr_list[0],pHostent->h_length); iErrorCode=bind(SockRaw,(SOCKADDR *)&sa,sizeof(SOCKADDR_IN)); CheckSockError(iErrorCode,"bind"); DWORD dwBufferLen[10]; DWORD dwBufferInLen=1; DWORD dwBufferReturned=0; iErrorCode=WSAIoctl( SockRaw, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen), &dwBufferReturned, NULL, NULL     ); printf("%d",WSAGetLastError()); if(WSAGetLastError()==WSAEINVAL) cout<<"参数不合法"<<endl; CheckSockError(iErrorCode,"WSAloctl"); while(1) { memset(RecvBuf,0,sizeof(RecvBuf)); iErrorCode=recv(SockRaw,RecvBuf,sizeof(RecvBuf),0); CheckSockError(iErrorCode,"recv"); iErrorCode=DecodeIpPack(RecvBuf,iErrorCode); CheckSockError(iErrorCode,"DecodeIpPack"); }     return 0;}char *CheckProtocal(int iProtocal){  int i=0;  for(;i<MAX_PROTO_NUM;i++)  {  if(protoMap[i].num==iProtocal)  return protoMap[i].protoname;    }  return "";}int DecodeIpPack(char *buf,int iBufSize){IPHEAD *pIpHead;int iProtocal,iTTL;char szProtocal[MAX_PROTO_TEXT_LEN];char szSourceIp[MAX_ADDR_LEN],szDestIp[MAX_ADDR_LEN];SOCKADDR_IN source,dest;pIpHead=(IPHEAD *)buf;//协议识别程序,如果程序中没有指定ip协议中的几个上层协议,则退出iProtocal=pIpHead->protocal;strncpy(szProtocal,CheckProtocal(iProtocal),MAX_PROTO_TEXT_LEN);if(iProtocal==IPPROTO_TCP&&!ParamTcp)return true;    if(iProtocal==IPPROTO_UDP&&!ParamUdp)return true;if(iProtocal==IPPROTO_ICMP&&!ParamIcmp)return true;source.sin_addr.S_un.S_addr=pIpHead->sourceIp;strncpy(szSourceIp,inet_ntoa(source.sin_addr),MAX_ADDR_LEN);if(strFromIpFilter)if(strcmp(szSourceIp,strFromIpFilter))return true;dest.sin_addr.S_un.S_addr=pIpHead->destIp;strncpy(szDestIp,inet_ntoa(dest.sin_addr),MAX_ADDR_LEN);if(strDestIpFilter)if(strcmp(szDestIp,strDestIpFilter))return true;iTTL=pIpHead->ttl;printf("%s:",szProtocal);printf("%s-->%s\n",szSourceIp,szDestIp);printf(" BYTES is %d,TTL is %d\n",iBufSize,iTTL);//计算IP数据包头部长度 int iIpHeadLen=sizeof(ULONG)*(pIpHead->headLenIpVersion&0x0F);    //解码上层协议信息switch (iProtocal){case IPPROTO_TCP:DecodeTcpPack(buf+iIpHeadLen);           break;case  IPPROTO_UDP:DecodeUdpPack(buf+iIpHeadLen);  break;case  IPPROTO_ICMP:DecodeIcmpPack(buf+iIpHeadLen);     break;default:   break;}return true;}int DecodeTcpPack( char *TcpPack ){TCPHEAD *pTcpHead;pTcpHead=(TCPHEAD *)TcpPack;printf(" tcp port %d-->tcp port %d\n",ntohs(pTcpHead->sourcePort),ntohs(pTcpHead->destPort));UCHAR mask=1;for(int i=0;i<6;i++){if(pTcpHead->reserve_flag&mask)printf("%c",tcpFlag[i]);elseprintf("-");mask=mask<<1;}printf("\n");return true;}int DecodeUdpPack( char *UdpPack ){UDPHEAD *pUdpHead;pUdpHead=(UDPHEAD *)UdpPack;printf("udp port %d--> udp port %d\n",ntohs(pUdpHead->sourcePort),ntohs(pUdpHead->destPort));printf(" Udp len -->%d\n",ntohs( pUdpHead->totalLen ));printf("\n");return true;}int DecodeIcmpPack(char *IcmpPack){    ICMPHEAD *pIcmpHead;pIcmpHead=(ICMPHEAD *)IcmpPack;printf("Type %d %d",pIcmpHead->type,pIcmpHead->code);printf("ID = %d, SEQ=%d\n",pIcmpHead->id,pIcmpHead->seq);return true;}void CheckSockError(int iErrorCode,char *pErrorMsg){if(iErrorCode==SOCKET_ERROR){printf("%s Error: %s",pErrorMsg,GetLastError());closesocket(SockRaw);exit(0);}}bool GetCmdLine(int argc,char **argv){   cout<<"参数有四个"<<endl;  if(argc<2)return CMD_PARAM_HELP;for(int i=1;i<argc;i++){  if(argv[i][0]!='/')  return CMD_PARAM_HELP;  else      switch(argv[i][1])      {  case 't':  case 'T': ParamTcp=true; break;  case 'u':  case 'U': ParamUdp=true; break;  case 'i':   case 'I': ParamIcmp=true;  break;  case 'p':  case 'P': ParamDecode=true; break;  case 'f':  case 'F':   {  strFromIpFilter=(char *)malloc(sizeof(char));   memset(strFromIpFilter,0,sizeof(char)*16);  strcpy(strFromIpFilter,argv[i]+3);              break;  }  case 'd':  case 'D':   {  strFromIpFilter=(char *)malloc(sizeof(char));   memset(strFromIpFilter,0,sizeof(char)*16);  strcpy(strFromIpFilter,argv[i]+3);  break;  }       }      }cout<<"\nNow I Will Sniff"<<endl;if(ParamTcp)cout<<"TCP"<<endl;if(ParamUdp)cout<<"UDP"<<endl;if(ParamIcmp)cout<<"ICMP"<<endl;if(strFromIpFilter)cout<<"From Ip:%s"<<strFromIpFilter<<endl;if(strDestIpFilter)cout<<"Dest Ip:%s"<<strDestIpFilter<<endl; return false;}void usage(){  cout<<"sniffer program!"<<endl;  cout<<"/t output tcp pakets!"<<endl;   cout<<"/u output udp pakets!"<<endl;    cout<<"/i output icmp pakets!"<<endl; cout<<"/p Decode pakets!"<<endl;  cout<<"/f output packet from IP"<<endl;       cout<<"/d output packet dest IP"<<endl;  }

经验1   如果编译后很多错误,一般是windows.h位置不对,要放入头文件包含的最后面

经验2  注意参数····socket函数的三个参数··不要写成SOCK_STREAM

0 0
原创粉丝点击