高手请进:怎么样解析固定端口上收发的数据包中的内容(在线等)

wangpengcheng 2004-07-18 07:13:25
怎么样解析固定端口上收发的数据包中的内容??

我是利用Sniffer的原理,监测所有收发的数据包,然后去掉相关的头部,得到包中的数据.将其转化为字符串类型.

我在机器上装了个邮件服务器,试着检测在25端口和110端口上的数据包.我认为可以把 user ,pass, mail from, rcpt to等命令相关的数据解析出来.可我试了好久,都没有结果.

当我从局域网中别的机子拷个 .txt文件 或者 向别的机子拷个 txt文件时,文件肯定是被打成几个包发送,但第一个包(文件最前面的一部分数据)是监测到了,而且大小都正确,但解析出的字符串却是空串,后面的几个包完全正确.

这个问题让我郁闷了好久,烦请大家帮我解决一下.

使用的代码如下:


#define MAX_HOSTNAME_LAN 255
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
#define MAX_ADDR_LEN 16

typedef struct tcpheader
{
unsigned short int sport;//信源端口
unsigned short int dport;//信宿端口
unsigned int th_seq;//序列号
unsigned int th_ack;//确认号
unsigned char th_x2:4;//
unsigned char th_off:4;//数据偏移,长度为4位
unsigned char Flags;//标志位
unsigned short int th_win;//窗口域
unsigned short int th_sum;//校验和
unsigned short int th_urp;//紧急指针
}TCP_HDR;

struct ipheader
{
unsigned char ip_hl:4, ip_v:4; //IP头长度和IP版本号,各4位
unsigned char ip_tos;//服务类型
unsigned short int ip_len;//总长度
unsigned short int ip_id;//标识符
unsigned short int ip_off;//片偏移
unsigned char ip_ttl;//生存时间
unsigned char ip_p;//协议
unsigned short int ip_sum;//头校验和
unsigned int ip_src;//信源端口
unsigned int ip_dst;//信宿端口
};

typedef struct udphdr
{
unsigned short sport;//信源端口
unsigned short dport;//信宿端口
unsigned short len;//总长度
unsigned short cksum;//校验和
}UDP_HDR;








SOCKET sock;
WSADATA wsd;//wsd为指向WSADATA结构的指针
DWORD dwBytesRet;
int pCount=0;
unsigned int optval = 1;
unsigned char *datatcp=NULL;
unsigned char *dataudp=NULL;
int lentcp=0, lenudp;

WSAStartup(MAKEWORD(2,1),&wsd);//初始化WINSOCK
if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==SOCKET_ERROR)// 创建原始套接字
exit(1);

char FAR name[MAX_HOSTNAME_LAN];
gethostname(name, MAX_HOSTNAME_LAN);//获取本机名

struct hostent FAR * pHostent;
pHostent = (struct hostent * )malloc(sizeof(struct hostent));
pHostent = gethostbyname(name);//获取给定主机名的IP地址

SOCKADDR_IN sa;
sa.sin_family = AF_INET;//填充SOCKADDR_IN结构
sa.sin_port = htons(6000);
memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);

bind(sock, (SOCKADDR *)&sa, sizeof(sa));//将原始套接字绑定到本地网卡上
if ((WSAGetLastError())==10013)
exit(1);

WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL);

struct udphdr *pUdpheader;
struct ipheader *pIpheader;
struct tcpheader *pTcpheader;
char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN];
SOCKADDR_IN saSource, saDest;



while(1)
{
char RecvBuf[65535] = {0};

pIpheader=(struct ipheader *)RecvBuf;//pIpheader指向IP包头部
pTcpheader=(struct tcpheader *)(RecvBuf+sizeof(struct ipheader));//pTcpheader指向TCP包头部
pUdpheader=(struct udphdr *)(RecvBuf+sizeof(struct ipheader));//pUdpheader指向UDP包头部

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

recv(sock, RecvBuf, sizeof(RecvBuf), 0);//从套接字接收数据

saSource.sin_addr.s_addr = pIpheader->ip_src;//信源端口
strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN);//szSourceIP中放的是数据的信源IP地址,用点分

十进制表示

saDest.sin_addr.s_addr = pIpheader->ip_dst;//信宿端口
strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN);//szDestIP中放的是数据的信宿IP地址,用点分十进制

表示

lentcp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct tcpheader)));//TCP数据包长度=IP包总

长度-IP头长度-TCP头长度
lenudp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct udphdr)));//UCP数据包长度=IP包总长

度-IP头长度-UDP头长度

if((pIpheader->ip_p)==IPPROTO_TCP&&lentcp!=0)//若这个数据包采用的是TCP协议
{

pCount++;
datatcp=(unsigned char *)RecvBuf+sizeof(struct ipheader)+sizeof(struct tcpheader);

CString temp="";
CString sourceIp(szDestIP);
CString destIP(szSourceIP);

int destPort = ntohs(pTcpheader->dport);
int sourcePort = ntohs(pTcpheader->sport);
temp.Format("%d",destPort);

CString s;
s.Format("%d", sourcePort);

MessageBox("协议:TCP \nIP源地址:"+sourceIp + " 源端口:"+s + "\n目的地址:" + destIP +"目的端口:"

+temp);


temp.Format("%d",lentcp);
MessageBox("tcp包的长度:"+temp);


CString data="";
for(int i=0;i {
temp = (CString)(*(char*)(datatcp+i));
data.Append(temp);
}

CString ss(data);
MessageBox(data);

if( (pIpheader->ip_p)==IPPROTO_UDP&&lentcp!=0)
{
//pCount++;
//dataudp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct udphdr);
//printf("-UDP-\n");
//printf("\nDestination address->%s\n",szDestIP);
//printf("\nDestination port->%d\n",ntohs(pTcpheader->dport));
//printf("dataudp address->%x\n",dataudp);
//printf("size of ipheader->%i\n",sizeof(struct ipheader));
//printf("size of udpheader->%i\n",sizeof(struct udphdr));
//printf("size of the hole packet->%i\n",ntohs(pIpheader->ip_len));
//printf("\nchar Packet%i []=\"",pCount,lenudp);
//for (int x=0;x //{
// printf("\\x%.2x",*(dataudp+x));
// if (x%10==0)
// {
// printf("\"");
// printf("\n\"");
// }
//}
//printf("\";\n\n\n");
//for (int x2=0;x2 //{
// if( *(dataudp+x2)<=127&&*(dataudp+x2)>=0)
// printf("%c",*(dataudp+x2));
// else
// printf(".");
//}
//printf("\n\n");
//printf("*******************************************\n");
}
}

...全文
311 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
crystal_heart 2004-07-22
  • 打赏
  • 举报
回复
up
wangpengcheng 2004-07-21
  • 打赏
  • 举报
回复
谁能帮我解决这个问题我一定加分重谢
new_guy 2004-07-21
  • 打赏
  • 举报
回复
我在XP下,没问题啊
PiggyXP 2004-07-21
  • 打赏
  • 举报
回复
在本机上的邮件发送的包好象没有检测到

====================================================================

很多朋友都反映说,也确实是有这样的情况存在,raw socket只是在2000系统下工作正常,在xp系统捕获不到发出的数据包..-_-b 楼主慎用

email分析你用sniffer随便抓几个email的数据包,去掉包头就可以看到诸如这些东西

AUTH LOGIN // 登录信息
235 Authentication successful
.....
.....

From: "Piggy" <Piggy.com@163.com> // 邮件内容
To: "Piggy" <Piggy.com@163.com>
Subject: asdasd
X-mailer: Foxmail 5.0 [cn]
Disposition-Notification-To: "Piggy" <Piggy.com@163.com>
Mime-Version: 1.0
Content-Type: text/plain;
charset="gb2312"
Content-Transfer-Encoding: base64

然后根据它的编码方式再来解码就好了,比如最后一行提示的base64等等,没什么深奥的呵呵^_^
muroachanf 2004-07-21
  • 打赏
  • 举报
回复
菜鸟来学习...
laker_tmj 2004-07-21
  • 打赏
  • 举报
回复
up
MFCClass 2004-07-19
  • 打赏
  • 举报
回复
我不会,学习
wangpengcheng 2004-07-18
  • 打赏
  • 举报
回复
至于我刚才说的拷贝文件,解析出来的英文能正常显示,而中文好象显示不出来,那就是因为你说的NetBIOS协议的原因吗?
要是因为那个原因的话,我搞不定 :(
wangpengcheng 2004-07-18
  • 打赏
  • 举报
回复
那么对于走25和110端口的邮件收发,怎么才能解析出其内容
老兄能否帮我在原本的基础上搞定?
我自己下载了一个邮件服务器,然后在本机上的邮件发送的包好象没有检测到:( 
帮我搞定后肯定重谢
PiggyXP 2004-07-18
  • 打赏
  • 举报
回复
而且一封mail一般都是分成多个数据包来发的,又或者几封mail同时混杂在多个数据包同时发出

所以楼主还需要考虑数据包的重组问题,最好是在把数据包重组完毕之后再开始分析
PiggyXP 2004-07-18
  • 打赏
  • 举报
回复
只有用foxmail等等这样专门的收发工具才是走的25和110端口,才能分析出与pop3和smtp服务器交互的命令,楼主的设想也才能实现

从web上收发邮件是走的80端口,就按照http的方法来分析

至于你说的拷贝文件,只与NetBIOS协议有关,和你的email分析是没有任何关系的

如果你信不过你自己的sniffer,就自己用个现成的工具抓个数据包打开看一下,除了包头或者网页中的图片之类的乱码以外,剩下的那些英文或者中文字符就是你想要的
gracezhu 2004-07-18
  • 打赏
  • 举报
回复
1。webmail 和pop3邮件格式不一样的,一个是http 80端口,一个是pop3协议,110端口。你用个sniffer工具抓下报文比较一下就知道了
2。没抓过这样的包,你用个sniffer工具先分析一下,然后自己再抓份看是否相同
new_guy 2004-07-18
  • 打赏
  • 举报
回复
没道理的。昨天小猪也帮我解决一个类似的问题。
估计是第一个包你解析,或者接受的长度有错误,
只收到包头,包头通常就是一些乱码。
wangpengcheng 2004-07-18
  • 打赏
  • 举报
回复
我这个程序能检测到局域网中所有的数据包(即使是与本机节点无关的包),但是包中的数据我不知道怎么解析出来,难道像前面老兄说的还与具体的协议有关?

当我从局域网中别的机子拷个 .txt文件 或者 向别的机子拷个 txt文件时,文件肯定是被打成几个包发送,但第一个包(文件最前面的一部分数据)是监测到了,而且大小都正确,但解析出的字符串却是空串,后面的几个包完全正确.??????????????????????谁能帮我解决这个问题
wangpengcheng 2004-07-18
  • 打赏
  • 举报
回复
现在我们发送邮件都是用一些邮件代理,都是在80端口上发送接收数据,
而SMTP是在25端口上.
但在80端口上,解析出来的字符串都是html格式的,根本就没有像smtp那样的命令,那么我要是想从检测的数据包中解析出来smtp的命令(即解析出是邮件的发送者,接收者,主题等信息),那该怎么办啊?
还有一点要注意的是,不同的邮件代理有不同的格式
new_guy 2004-07-18
  • 打赏
  • 举报
回复
M
我也想了解解包的过程。
简单的(char*)(buf+ip.len+tcp.len)
肯定不行。我想要解的是html包
用上面char了之后剩下http头,
然后就是字符处理的问题了。
如果楼主不嫌麻烦可以抓几个包下来分析下。
SMTP好象是明文的,应该可以看到内容。
gracezhu 2004-07-18
  • 打赏
  • 举报
回复
问题没看太懂。
1。既然你要监控邮件,就应该根据pop3,smtp协议来分析数据包内容
2。(当我从局域网中别的机子拷个 .txt文件 或者 向别的机子拷个 txt文件时),使用的是netbios端口,应该根据这个来分析。
从你的代码看,基本上只作出了解析出包头,具体的分析还得根据不同的协议和其对应的端口。
wangpengcheng 2004-07-18
  • 打赏
  • 举报
回复
我上面的程序屏蔽了 UDP的部分,只测试 TCP数据包
自由的风 2004-07-18
  • 打赏
  • 举报
回复
楼猪不简单,那么多代码要看死人啊

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧