#include "stdafx.h" #include "stdio.h" #include "string.h" #include "mstcpip.h" #include "Winsock2.h"
#pragma comment(lib,"WS2_32.lib")
#define STATUS_FAILED 0xFFFF??????????//定义异常出错代码 #define MAX_PACK_LEN 65535???????????//接收的最大
IP 报文 #define MAX_ADDR_LEN 16????????????//点分十进制
地址的最大长度 #define MAX_HOSTNAME_LAN 255??????????//最大主机名长度
typedef struct _iphdr????????????//定义IP首部 { unsigned char h_lenver;????????????//4
位首部长度+4 位IP 版本号 unsigned char tos;?????????????
//8 位服务类型TOS unsigned short total_len;???????????//16
位总长度(字节) unsigned short ident;????????????//16
位标识 unsigned short frag_and_flags;??????????//3 位标志位 unsigned char ttl;?????????????
//8 位生存时间TTL unsigned char proto;????????????//8
位协议(TCP 或其他) unsigned short checksum;???????????//16
位IP 首部校验和 unsigned int sourceIP;????????????//32
位源IP 地址 unsigned int destIP;????????????//32
位目的IP 地址 }IP_HEADER;
typedef struct _tcphdr????????????//定义TCP 首
部 { USHORT th_sport;?????????????
//16 位源端口 USHORT th_dport;?????????????
//16 位目的端口 unsigned int th_seq; unsigned int th_ack; unsigned char th_lenres;???????????//4
位首部长度/6 位保留字 unsigned char th_flag;????????????//6
位标志位 USHORT th_win;??????????????
//16 位窗口大小 USHORT th_sum;??????????????
//16 位校验和 USHORT th_urp;??????????????
//16 位紧急数据偏移量 }TCP_HEADER;
SOCKET SockRaw;????? char* TcpFlag[6]={?????????????//定
义TCP 标志位 "FIN ",?????????????
?//FIN: 表示发送端已经没有数据要求传输了,希望释放连接。 "SYN ",?????????????
?//SYN: 标志位用来建立连接,让连接双方同步序列号。如果SYN=1而ACK=0,则表示该数据包为连接请求,如果SYN=1而ACK=1则表示
接受连接。 "RST ",?????????????
?//RST: 用来复位一个连接。RST标志置位的数据包称为复位包。一般情况下,如果TCP收到的一个分段明显不是属于该主机上的任何一
个连接,则向远端发送一个复位包。 "PSH ",?????????????
?//PSH: 如果置位,接收端应尽快把数据传送给应用层。 "ACK ",?????????????
?//ACK: 为确认标志位。如果为1,表示包中的确认号时有效的。否则,包中的确认号无效。 "URG "?????????????
?//URG: 为紧急数据标志。如果它为1,表示本数据包中包含紧急数据。此时紧急数据指针有效。 };????? bool ParamTcp =true;????????????// -t 关注TCP
报文 char *strFromIpFilter=NULL;???????????// 源IP 地址
过滤 char *strDestIpFilter=NULL;???????????// 目的地址过
滤
//Referrence int DecodeIpPack(char *,int); int DecodeTcpPack(char *); void CheckSockError(int,char*); void usage(void); bool GetCmdLine(int, char **);
// void main(int argc, char ** argv) { int iErrorCode; char RecvBuf[MAX_PACK_LEN] = { 0 }; usage(); if(GetCmdLine(argc, argv)==true) exit(0);
//初始化SOCKET WSADATA wsaData; iErrorCode = WSAStartup(MAKEWORD(2,1), &wsaData); CheckSockError(iErrorCode, "WSAStartup"); SockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP); CheckSockError(SockRaw, "socket");
//获取本机IP 地址 char FAR name[MAX_HOSTNAME_LAN]; iErrorCode = gethostname(name, MAX_HOSTNAME_LAN); CheckSockError(iErrorCode, "gethostname"); struct hostent FAR * pHostent; pHostent = (struct hostent * )malloc(sizeof(struct hostent)); pHostent = 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, (PSOCKADDR) &sa, sizeof(sa)); CheckSockError(iErrorCode, "bind");
//设置SOCK_RAW 为SIO_RCVALL,以便接收所有的IP 包 DWORD dwBufferLen[10] ; DWORD dwBufferInLen = 1 ; DWORD dwBytesReturned = 0 ; iErrorCode=WSAIoctl(SockRaw, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned, NULL, NULL ); CheckSockError(iErrorCode, "Ioctl");
//侦听IP 报文 while(true) { memset(RecvBuf, 0, sizeof(RecvBuf)); iErrorCode = recv(SockRaw, RecvBuf, sizeof(RecvBuf), 0); CheckSockError(iErrorCode, "recv"); iErrorCode = DecodeIpPack(RecvBuf, iErrorCode); CheckSockError(iErrorCode, "Decode"); } }
//IP 解包程序 int DecodeIpPack(char *buf, int iBufSize) { IP_HEADER *pIpheader; int iProtocol, iTTL; char szProtocol[4]; char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN]; SOCKADDR_IN saSource, saDest; pIpheader = (IP_HEADER *)buf;
?//Check Proto iProtocol = pIpheader- >proto; strncpy(szProtocol, "TCP", 4); if(iProtocol==IPPROTO_TCP) { //Check Source IP saSource.sin_addr.s_addr = pIpheader- >sourceIP; strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN); if (strFromIpFilter) if (strcmp(strFromIpFilter,szSourceIP)) return true;
??//Check Dest IP saDest.sin_addr.s_addr = pIpheader- >destIP; strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN); if (strDestIpFilter) if (strcmp(strDestIpFilter,szDestIP)) return true;
??//TTL iTTL = pIpheader- >ttl;
??//Output printf( "%s ", szProtocol); printf( "%s->%s ", szSourceIP, szDestIP); printf( "bytes=%d TTL=%d ",iBufSize,iTTL);
??//Calculate IP Header Length int iIphLen = sizeof(unsigned long) * (pIpheader- >h_lenver & 0xf);
??//Decode Sub Protocol:TCP DecodeTcpPack(buf+iIphLen); } return true; }
//SOCK 错误处理程序 void CheckSockError(int iErrorCode, char *pErrorMsg) { if(iErrorCode==SOCKET_ERROR) { printf( "%s Error:%d\n", pErrorMsg, GetLastError()); closesocket(SockRaw); exit(0); } }
//TCP 解包程序 int DecodeTcpPack(char * TcpBuf) { TCP_HEADER * pTcpHeader; pTcpHeader = (TCP_HEADER * )TcpBuf; printf( "Port:%d->%d ", ntohs(pTcpHeader->th_sport),ntohs(pTcpHeader->th_dport)); unsigned char FlagMask = 1; int HdrLen = (pTcpHeader- >th_lenres)>>2; printf( "\n%s",((BYTE *)pTcpHeader)+HdrLen); for( int i=0; i <6; i++ ) { if((pTcpHeader- >th_flag) & FlagMask) printf( "%s",TcpFlag); else printf( " "); FlagMask=FlagMask <<1; } printf( "\n"); return true; }
//命令行参数处理 bool GetCmdLine(int argc, char ** argv) { for(int i=1;i <argc;i++) { if(argv[0]!='/') return true; else { switch (argv[1]) { case 'f': case 'F': { strFromIpFilter=(char*)malloc(16*sizeof(char)); memset(strFromIpFilter,0,16*sizeof(char)); strcpy(strFromIpFilter,argv+3); break; } case 'd': case 'D': { strDestIpFilter=(char*)malloc(16*sizeof(char)); memset(strDestIpFilter,0,16*sizeof(char)); strcpy(strDestIpFilter,argv+3); break; } case '?': return true; break; default: break; } } } printf( "\nWill Sniffer"); printf( " TCP"); if(strFromIpFilter) printf( " FromIp:%s",strFromIpFilter); if(strDestIpFilter) printf( " DestIp:%s",strDestIpFilter); printf( "\n\tCTRL+C to quit\nStart:\n"); return (false); }
void usage(void) { printf( "\tSinffer for Win2K Console\n"); printf( "USAGE:\n"); printf( "\t/f: fromIP Output Packets FromIp=fromIP (default ALL)\n"); printf( "\t/d: destIP Output Packets DestIp=destIP (default ALL)"); printf( "\nExample:\n"); printf( "\tsniffer.exe /d:192.168.15.233\n"); printf( "\tsniffer.exe /f:192.168.15.231\n");
|