1.目前根据tcp协议,端口号(993),imap协议,过滤出收到邮件的数据。
2.怎么根据收到的数据报文,还原出邮件的内容?????
相关代码
void packet_handler(u_char* param, const pcap_pkthdr* header, const u_char* pkt_data)
{
pcap_dump(param, header, pkt_data);
struct tm* ltime;
char timestr[16];
time_t local_tv_sec;
ip_header* ih;
udp_header* uh;
u_int ip_len;
u_short sport, dport;
//数据部分的长度
int dataLength;
dataLength = header->caplen;
//tcp的头指针=tcp的头指针=ip头指针+ip包头的长度
tcp_header* tcph;
//Tcp数据的头指针 tcp数据头指针=tcp的头指针+tcp包头长度
u_char* datantry;
int tcp_len;
/* 将时间戳转换成可识别的格式 */
local_tv_sec = header->ts.tv_sec;
ltime = localtime(&local_tv_sec);
strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);
//printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
/* 打印数据包的时间戳和长度 */
printf("时间戳:%s.%.6d 数据包长度:%d ", timestr, header->ts.tv_usec, header->len);
/* 获得IP数据包头部的位置 */
ih = (ip_header*)(pkt_data +
14); //以太网头部长度
//printf("协议类型:%d\r\n", ih->proto);
/* 获得TCP首部的位置 */
ip_len = (ih->ver_ihl & 0xf) * 4;
uh = (udp_header*)((u_char*)ih + ip_len);
tcph = (tcp_header*)((u_char*)ih + ip_len); //tcp的头指针=ip头指针+ip包头的长度
tcp_len = (tcph->th_lenres & 0xf0) / 4; //tcp->ver_thl & 0xf0表示取四位tcp_len
datantry = (u_char*)((u_char*)tcph + tcp_len); //tcp数据头指针=tcp的头指针+tcp包头长度
/* 将网络字节序列转换成主机字节序列 */
sport = ntohs(uh->sport);
dport = ntohs(uh->dport);
dataLength = dataLength - 14 - ip_len - tcp_len; //这个2指(0d0a)
bool is_pause = false;
//判断tcp协议类型协议
char http_type[4096] = "未知";
if (ih->proto == 6) //说明是tcp协议 6tcp 17udp icmp1 igmp2
{
printf("\n开始分析tcp/ip数据包...\n");
int ip_len = ntohs(ih->tlen); /* get ip length, it contains header and body */
int find_http = false;
char* ip_pkt_data = (char*)ih;
int n = 0;
char buffer[65535];
int bufsize = 0;
//判断是HTTP的请求报文,还是响应报文 1请求(POST/GET) 2 响应(HTTP/1.1) 0不是http协议的报文
int is_req_res = 0;
//根据端口分析是那种类型25smtp(发送协议) 110 pop3(接受协议)
if (dport == 80) //http协议
{
for (; n < ip_len; n++)
{
/* http get or post request */
if (!find_http && ((n + 3 < ip_len && strncmp(ip_pkt_data + n, "GET", strlen("GET")) == 0)
|| (n + 4 < ip_len && strncmp(ip_pkt_data + n, "POST", strlen("POST")) == 0)))
{
find_http = true;
is_req_res = 1;
}
/* http response */
if (!find_http && n + 8 < ip_len && strncmp(ip_pkt_data + n, "HTTP/1.1", strlen("HTTP/1.1")) == 0)
{
find_http = true;
is_req_res = 2;
}
/* if http is found */
if (find_http)
{
buffer[bufsize] = ip_pkt_data[n]; /* copy http data to buffer */
bufsize++;
}
}
/* print http content */
if (find_http)
{
buffer[bufsize] = '\0';
printf("%s\n", buffer);
printf("\n**********************************************\n");
is_pause = true;
//system("pause");
}
}
if (dport == 25)
{
printf("\r\n\r\n检测到发送邮件\r\n");
#if 1
system("pause");
#endif //是否遇到发送邮件暂停
}
if (dport == 143) //pop3协议 邮件接受协议
{
printf("\r\n\r\n检测到收到邮件1\r\n");
system("pause");
}
if ( dport == 993 ) //pop3协议 邮件接受协议 993
{
printf("\r\n\r\n检测到收到邮件2\r\n");
//对邮件的处理还原
printf("DATA:%d\r\n", pkt_data);
#if 1
system("pause");
#endif //是否遇收到邮件暂停
}
}
/* 打印IP地址和UDP端口 */
printf("源ip:%d.%d.%d.%d.源端口;%d -> 目的ip:%d.%d.%d.%d.目的端口:%d ------协议类型:%d\r\n\n\n",
ih->saddr.byte1,
ih->saddr.byte2,
ih->saddr.byte3,
ih->saddr.byte4,
sport,
ih->daddr.byte1,
ih->daddr.byte2,
ih->daddr.byte3,
ih->daddr.byte4,
dport, ih->proto
);
//保存每帧的数据包
//pcap_dump(param, header, pkt_data);
#if 0
if (is_pause)
system("pause");
#endif //是否遇到HTTP报文暂停
}
运行相关截图:
解析为utf-8的方式进行解析。