Java嗅探端口协议_嗅探器的实现 对协议的分析(转)

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

#pragma comment (lib, "ws2_32.lib")

#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)

#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 // 最大主机名长度

// 定义IP首部格式

typedef struct _IPHeader

{

unsigned char h_verlen; // 版本和首部长度

unsigned char tos; // 服务类型

unsigned short total_len; // 总长度

unsigned short ident; // 标识号

unsigned short frag_and_flags; // 段偏移量

unsigned char ttl; // 生存时间

unsigned char proto; // 协议

unsigned short checksum; // 首部校验和

unsigned int sourceIP; // 源IP地址

unsigned int destIP; // 目的地址

}IPHEADER;

// 定义TCP首部格式

typedef struct _TCPHeader

{

unsigned short th_sport; // 源端口号

unsigned short th_dport; // 目的端口号

unsigned int th_seq; // SEQ序号

unsigned int th_ack; // ACK序号

unsigned char th_lenres; // 首部长度

unsigned char th_flag; // 控制位

unsigned short th_win; // 窗口大小

unsigned short th_sum; // 校验和

unsigned short th_urp; // 紧急指针

}TCPHEADER;

// 定义UDP首部格式

typedef struct _UDPHeader

{

unsigned short uh_sport; // 16位源端口

unsigned short uh_dport; // 16位目的端口

unsigned short uh_len; // 16位长度

unsigned short uh_sum; // 16位校验和

}UDPHEADER;

// 定义ICMP首部格式

typedef struct _ICMPHeader

{

BYTE i_type; // 8位类型

BYTE i_code; // 8位代码

unsigned short i_cksum; // 16位校验和

unsigned short i_id; // 识别号

unsigned short i_seq; // 报文序列号

unsigned long timestamp; // 时间戳

}ICMPHEADER;

//----------------------------------------------------------------------------------------------

// 定义子协议映射表

typedef struct _protomap

{

int ProtoNum;

char ProtoText[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 paramAll = false; // 嗅探所有的数据包

bool paramTcp = false; // 嗅探TCP数据包

bool paramUdp = false; // 嗅探UDP数据包

bool paramIcmp = false; // 嗅探ICMP数据包

int packet_totallen = 0; // 数据包总长度

char paramHostAddr_A[20]; // 嗅探的主机A

char paramHostAddr_B[20]; // 嗅探的主机B

char keyword[100]; // 嗅探的关键信息

// IP数据包解析函数

int DecodeIpPack(char *);

// TCP数据包解析函数

int DecodeTcpPack(char *);

// UDP数据包解析函数

int DecodeUdpPack(char *);

// ICMP数据包解析函数

int DecodeIcmpPack(char *);

// 显示数据包信息

void ShowPackInfo(char *buf, int iProtocol, char *szSoueceIP, char *szDestIP, char *szProtocol);

// 显示子协议数据包函数

void ShowSubPackInfo(char *, int);

// 错误检测函数

void CheckSockError(int, char*);

// 协议检测函数

char *CheckProtocol(int);

// 设置嗅探器参数函数

bool SetSnifferParam();

//-----------------------------------------------------------------------------------------------------

// SOCK错误处理函数

void CheckSockError(int iErrorCode, char *pErrorMsg)

{

if(iErrorCode == SOCKET_ERROR)

{

printf("%s 出错了: %d",pErrorMsg,GetLastError());

closesocket(SockRaw);

exit(0);

}

}

//------------------------------------------------------------------------------------------------------

// 协议识别函数

char *CheckProtocol(int iProtocol)

{

for(int i=0; i

{

// 如果找到对应的子协议,则返回名称

if(ProtoMap[i].ProtoNum == iProtocol)

{

return ProtoMap[i].ProtoText;

}

}

return "";

}

//---------------------------------------------------------------------------------------------------------

// TCP解包函数

int DecodeTcpPack(char *TcpBuf)

{

TCPHEADER *pTcpHeader;

char data[MAX_PACK_LEN];

int i;

// 转换成TCP首部格式

pTcpHeader = (TCPHEADER*)TcpBuf;

// 输出源端口和目的端口

printf(" 端口 : %d-->%d ",ntohs(pTcpHeader->th_sport),ntohs(pTcpHeader->th_dport));

unsigned char FlagMask = 1;

// 输出标志位

//printf("标志位:");

for(i=0;i<6;i++)

{

if((pTcpHeader->th_flag) & FlagMask)

{

printf("标志位:%c",TcpFlag[i]);

}

else

{

printf("-");

}

FlagMask = FlagMask<<1;

}

printf("\n");

// 求数据段长度

int totalheadlen = sizeof(IPHEADER)+sizeof(TCPHEADER);

int tcpheadlen = sizeof(TCPHEADER);

memcpy(data,TcpBuf+tcpheadlen,packet_totallen-totalheadlen);

return true;

}

//-------------------------------------------------------------------------------------------------------------

// UDP 解包函数

int DecodeUdpPack(char *UdpBuf)

{

UDPHEADER *pUdpHeader;

char data[MAX_PACK_LEN];

pUdpHeader = (UDPHEADER *)UdpBuf;

// 输出端口和数据长度

printf(" 端口号: %d-->%d ",ntohs(pUdpHeader->uh_sport),ntohs(pUdpHeader->uh_dport));

printf(" 长度: %d\n",ntohs(pUdpHeader->uh_len));

int totalheadlen = sizeof(IPHEADER)+sizeof(UDPHEADER);

int udpheadlen = sizeof(UDPHEADER);

memcpy(data,UdpBuf+udpheadlen,packet_totallen-totalheadlen);

return true;

}

//---------------------------------------------------------------------------------------------------------------------

// ICMP 解包函数

int DecodeIcmpPack(char *IcmpBuf)

{

ICMPHEADER *pIcmpHeader;

pIcmpHeader = (ICMPHEADER *)IcmpBuf;

// 输出ICMP数据包类型、ID和SEQ

printf(" Type : %d,%d",pIcmpHeader->i_type,pIcmpHeader->i_code);

printf(" ID = %d SEQ = %d\n",pIcmpHeader->i_id,pIcmpHeader->i_seq);

return true;

}

//-----------------------------------------------------------------------------------------------------------------------

// 根据过滤条件显示数据包信息

void ShowPackInfo(char *buf, int iProtocol, char *szSoueceIP, char *szDestIP, char *szProtocol)

{

// 如果设置了主机B的IP,没有设置主机A的IP

if((!strcmp(paramHostAddr_A,"all")) && (strcmp(paramHostAddr_B,"all")))

{

if((!strcmp(paramHostAddr_B,szSoueceIP))

|| (!strcmp(paramHostAddr_B,szDestIP)))

{

printf(" -------------------------------------------------------------------------------\n");

printf("| 协议| 源IP地址 | 目的IP地址 | ");

printf("------------------------------------------------------------------------------\n");

printf("\n| %s | ",szProtocol);

printf(" %s | %s |",szSoueceIP,szDestIP);

// 显示子协议数据包相关信息

ShowSubPackInfo(buf,iProtocol);

}

}

// 如果设置主机A的IP,没有设置主机B的IP

else if((strcmp(paramHostAddr_A,"all")) && (!strcmp(paramHostAddr_B,"all")))

{

if((!strcmp(paramHostAddr_A,szSoueceIP))

|| (!strcmp(paramHostAddr_A,szDestIP)))

{

printf(" -------------------------------------------------------------------------------\n");

printf("| 协议| 源IP地址 | 目的IP地址 |\n ");

printf("------------------------------------------------------------------------------");

printf("\n| %s | ",szProtocol);

printf(" %s | %s |",szSoueceIP,szDestIP);

ShowSubPackInfo(buf,iProtocol);

}

}

// 如果主机A和B的IP都进行了设置

else if((strcmp(paramHostAddr_A,"all")) && (strcmp(paramHostAddr_B,"all")))

{

if((!strcmp(paramHostAddr_A,szSoueceIP)

&& !strcmp(paramHostAddr_B,szDestIP))

|| (!strcmp(paramHostAddr_B,szSoueceIP)

&& !strcmp(paramHostAddr_A,szDestIP)))

{

printf(" -------------------------------------------------------------------------------\n");

printf("| 协议| 源IP地址 | 目的IP地址 |\n ");

printf("------------------------------------------------------------------------------");

printf("\n| %s | ",szProtocol);

printf(" %s | %s |",szSoueceIP,szDestIP);

ShowSubPackInfo(buf,iProtocol);

}

}

// 如果主机A和B的IP都没有进行设置

else

{

printf(" -------------------------------------------------------------------------------\n");

printf("| 协议| 源IP地址 | 目的IP地址 |\n ");

printf("------------------------------------------------------------------------------");

printf("\n| %s | ",szProtocol);

printf(" %s | %s |",szSoueceIP,szDestIP);

ShowSubPackInfo(buf,iProtocol);

}

}

//-----------------------------------------------------------------------------------------------------------------------

// 显示子协议数据包信息

void ShowSubPackInfo(char *buf, int iProtocol)

{

switch(iProtocol)

{

case IPPROTO_TCP: // TCP数据包

DecodeTcpPack(buf);

break;

case IPPROTO_UDP: // UDP数据包

DecodeUdpPack(buf);

break;

case IPPROTO_ICMP: // ICMP数据包

DecodeIcmpPack(buf);

break;

default:

break;

}

}

// IP 解包函数

int DecodeIpPack(char *buf)

{

//cout<

IPHEADER *pIpHeader;

int iProtocol;

// 定义协议

char szProtocol[MAX_PROTO_TEXT_LEN];

char szSourceIP[MAX_ADDR_LEN];

char szDestIP[MAX_ADDR_LEN];

SOCKADDR_IN saSource,saDest;

pIpHeader = (IPHEADER *)buf;

// 检测协议是哪种类型

iProtocol = pIpHeader->proto;

strncpy(szProtocol,CheckProtocol(iProtocol),MAX_PROTO_TEXT_LEN);

// 检测源地址

saSource.sin_addr.s_addr = pIpHeader->sourceIP;

strncpy(szSourceIP,inet_ntoa(saSource.sin_addr),MAX_ADDR_LEN);

// 检测目的地址

saDest.sin_addr.s_addr = pIpHeader->destIP;

strncpy(szDestIP,inet_ntoa(saDest.sin_addr),MAX_ADDR_LEN);

int iIpLen = sizeof(unsigned long)*(pIpHeader->h_verlen & 0xf);

packet_totallen = ntohs(pIpHeader->total_len);

// 下面显示过滤信息

if(paramAll) // 显示所有协议类型数据包

{

ShowPackInfo(buf+iIpLen,iProtocol,szSourceIP,szDestIP,szProtocol);

}

// 显示TCP类型数据包

else if(paramTcp && (iProtocol == IPPROTO_TCP))

{

ShowPackInfo(buf+iIpLen,iProtocol,szSourceIP,szDestIP,szProtocol);

}

// 显示UDP类型数据包

else if(paramUdp && (iProtocol == IPPROTO_UDP))

{

ShowPackInfo(buf+iIpLen,iProtocol,szSourceIP,szDestIP,szProtocol);

}

// 显示ICMP类型数据包

else if(paramIcmp && (iProtocol == IPPROTO_ICMP))

{

ShowPackInfo(buf+iIpLen,iProtocol,szSourceIP,szDestIP,szProtocol);

}

return true;

}

//------------------------------------------------------------------------------------------------------------

// 设置嗅探器参数

bool SetSnifferParam()

{

int ret;

bool check_input = false;

while(!check_input)

{

printf("*************************基于原始套接字的网络嗅探器*****************************\n\n");

printf(" 学号:3109005953 姓名:卫海鹏 专业班级:2009级计算机科学与技术(2)班 \n\n");

printf("==>>请选择要嗅探的数据包类型: 0. 全部 1. TCP 2. UDP 3. ICMP : ");

scanf("%d",&ret);

switch(ret)

{

case 0:

paramAll = true;

check_input = true;

break;

case 1:

paramTcp = true;

check_input = true;

break;

case 2:

paramUdp = true;

check_input = true;

break;

case 3:

paramIcmp = true;

check_input = true;

break;

default:

printf("==>>o(︶︿︶)o唉,输入错误!!!\n");

check_input = false;

break;

}

}

printf("\n==>>请输入嗅探的主机A的IP地址(输入all即为全部主机):");

scanf("%s",paramHostAddr_A);

printf("\n==>>请输入嗅探的主机B的IP地址(输入all即为全部主机):");

scanf("%s",paramHostAddr_B);

return true;

}

//----------------------------------------------------------------------------------------------------------------------

void main(int argc, char **argv)

{

int i,temp;

int iErrorCode;

char RecvBuf[MAX_PACK_LEN] = {0};

SetSnifferParam();

WSADATA wsaData;

// 初始化Winsock库

iErrorCode = WSAStartup(MAKEWORD(2,1),&wsaData);

CheckSockError(iErrorCode, "WSAStartup");

SockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

CheckSockError(SockRaw, "socket");

// 获取本机IP地址,并且判断Socket版本,建立原始套接字

char FAR name[MAX_HOSTNAME_LEN];

iErrorCode = gethostname(name, MAX_HOSTNAME_LEN);

CheckSockError(iErrorCode, "gethostname");

printf("%s\n",name);

struct hostent FAR *pHostent;

pHostent = (struct hostent *)malloc(sizeof(struct hostent));

pHostent = gethostbyname(name);

cout<h_name:"<h_name<

cout<h_aliases:"<h_aliases<

cout<h_addrtype:"<h_addrtype<

cout<h_length:"<h_length<

cout<h_addr_list:"<h_addr_list<

// 设置地址结构,端口为本地的6000

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");

// 设置套接字为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报文

L1: printf("\n==>>请输入要嗅探数据包的个数:");

scanf("%d",&temp);

i=temp;

while(i)

{

// 每次将接收缓冲区清零

memset(RecvBuf, 0, sizeof(RecvBuf));

// 开始接收缓冲区的数据

iErrorCode = recv(SockRaw, RecvBuf, sizeof(RecvBuf),0);

CheckSockError(iErrorCode, "recv");

// 对接收到的数据包进行解析

iErrorCode = DecodeIpPack(RecvBuf);

CheckSockError(iErrorCode, "Decode");

Sleep(100);

i--;

}

if(i % 10 == 0) {

system("pause");

goto L1;

} //等待输入一个字符(不回显)后继续输出.

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值