计算机网络课程设计编程实现简单的TCP协议分析器_计算机网络课程设计

2020-02-27 协议书 下载本文

计算机网络课程设计编程实现简单的TCP协议分析器由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“计算机网络课程设计”。

编程实现简单的TCP协议分析器

编程实现简单的TCP协议分析器

一、问题描述

编程实现简单的TCP协议分析器,TCP协议分析器是一种用于监督和跟踪网络活动的诊断工具,它从局域网中抓取IP数据包,并对它进行分析得到相应的头部信息,过滤TCP包进行分析,得到TCP包的相应信息。

二、基本要求

1.利用原始套接字实现简单的TCP协议分析器。2.系统功能包括:

2.1 原始套接字与网卡绑定,并接收流经网卡的所有数据包; 2.2 对数据包进行分析以获得源IP地址和目的IP地址; 2.3 对TCP Segment进行分析以获得其首部详细信息; 2.4 显示分析结果。3 建议使用VC++。

三、设计思想

TCP协议的数据传送程序是由二个子程序组成的。也可以看成是服务器端程序和客户端程序,其中:服务器端程序的功能是侦听端口号,接收远 程主要的TCP连接申请,并接收远程主机传送来的文字数据。另外一个子程序,也就是所谓的客户端程序,主要实现向网络的远程主机提出TCP连接申请。

程序利用原始套接字抓取局域网中的IP包。

TCP协议分析器实现了sniffer的一部分功能。而sniffer的工作原理是:1.把网卡置于混杂模式;2.捕获数据包;3.分析数据包。

Raw Socket: 原始套接字可以用它来发送和接收 IP 层以上的原始数据包, 如 ICMP,TCP, UDP等。

四、系统结构

(1)Pcap_addr描述网络接口地址;

(2)pcap_pkthdr用来描述每个捕获到的数据包的基本信息;(3)int_pcaplookupnet获取网络地址和网络掩码;

(4)int_pcaploop循环捕获网络数据包,直到遇到错误或满足退出条件;(5)pcap_t* pcap_open_dead构造一个libpcap句柄。

五、程序流程(或模块划分)

编程实现简单的TCP协议分析器

六、源程序

#include “pcap.h” struct ether_header {

u_int8_t ether_dhost[6];

/* 目的以太网地址 */

u_int8_t ether_shost[6];

/* 源以太网地址 */

u_int16_t ether_type;

/* 以太网类型 */ };struct arp_header

编程实现简单的TCP协议分析器

{

u_int16_t arp_hardware_type;

/* 硬件类型 */

u_int16_t arp_protocol_type;

/* 协议类型 */

u_int8_t arp_hardware_length;

/* 硬件地址长度 */

u_int8_t arp_protocol_length;

/* 协议地址长度 */

u_int16_t arp_operation_code;

/* 操作码 */

u_int8_t arp_source_ethernet_addre[6];

/* 源以太网地址 */

u_int8_t arp_source_ip_addre[4];

/* 源IP地址 */

u_int8_t arp_destination_ethernet_addre[6];

/* 目的以太网地址 */

u_int8_t arp_destination_ip_addre[4];

/* 目的IP地址 */ };struct ip_header {

#if defined(WORDS_BIGENDIAN)

u_int8_t ip_version: 4,/* 版本 */

ip_header_length: 4;

/* 首部长度 */

#else

u_int8_t ip_header_length: 4, ip_version: 4;

#endif

u_int8_t ip_tos;

/* 服务质量 */

u_int16_t ip_length;

/* 长度 */

u_int16_t ip_id;

/* 标识 */

u_int16_t ip_off;

编程实现简单的TCP协议分析器

/* 偏移 */

u_int8_t ip_ttl;

/* 生存时间 */

u_int8_t ip_protocol;

/* 协议类型 */

u_int16_t ip_checksum;

/* 校验和 */

struct in_addr ip_souce_addre;

/* 源IP地址 */

struct in_addr ip_destination_addre;

/* 目的IP地址 */ };struct udp_header {

u_int16_t udp_source_port;

/* 源端口号 */

u_int16_t udp_destination_port;

/* 目的端口号 */

u_int16_t udp_length;

/* 长度 */

u_int16_t udp_checksum;

/* 校验和 */ };struct tcp_header {

u_int16_t tcp_source_port;

/* 源端口号 */

u_int16_t tcp_destination_port;

/* 目的端口号 */

u_int32_t tcp_sequence_liuzhen;

/* 序列号 */

u_int32_t tcp_acknowledgement;

/* 确认序列号 */

#ifdef WORDS_BIGENDIAN

u_int8_t tcp_offset: 4,/* 偏移 */

编程实现简单的TCP协议分析器

tcp_reserved: 4;

/* 未用 */

#else

u_int8_t tcp_reserved: 4,/* 未用 */

tcp_offset: 4;

/* 偏移 */

#endif

u_int8_t tcp_flags;

/* 标记 */

u_int16_t tcp_windows;

/* 窗口大小 */

u_int16_t tcp_checksum;

/* 校验和 */

u_int16_t tcp_urgent_pointer;

/* 紧急指针 */ };struct icmp_header {

u_int8_t icmp_type;

/* ICMP类型 */

u_int8_t icmp_code;

/* ICMP代码 */

u_int16_t icmp_checksum;

/* 校验和 */

u_int16_t icmp_id;

/* 标识符 */

u_int16_t icmp_sequence;

/* 序列码 */ };void tcp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content){

struct tcp_header *tcp_protocol;

/* TCP协议变量 */

u_char flags;

编程实现简单的TCP协议分析器

/* 标记 */

int header_length;

/* 长度 */

u_short source_port;

/* 源端口 */

u_short destination_port;

/* 目的端口 */

u_short windows;

/* 窗口大小 */

u_short urgent_pointer;

/* 紧急指针 */

u_int sequence;

/* 序列号 */

u_int acknowledgement;

/* 确认号 */

u_int16_t checksum;

/* 校验和 */

tcp_protocol =(struct tcp_header*)(packet_content + 14+20);

/* 获得TCP协议内容 */

source_port = ntohs(tcp_protocol->tcp_source_port);

/* 获得源端口 */

destination_port = ntohs(tcp_protocol->tcp_destination_port);

/* 获得目的端口 */

header_length = tcp_protocol->tcp_offset *4;

/* 长度 */

sequence = ntohl(tcp_protocol->tcp_sequence_liuzhen);

/* 序列码 */

acknowledgement = ntohl(tcp_protocol->tcp_acknowledgement);

/* 确认序列码 */

windows = ntohs(tcp_protocol->tcp_windows);

/* 窗口大小 */

urgent_pointer = ntohs(tcp_protocol->tcp_urgent_pointer);

/* 紧急指针 */

flags = tcp_protocol->tcp_flags;

/* 标识 */

checksum = ntohs(tcp_protocol->tcp_checksum);

编程实现简单的TCP协议分析器

/* 校验和 */

printf(“-------TCP协议

-------n”);

printf(“源端口号:%dn”, source_port);

printf(“目的端口号:%dn”, destination_port);

switch(destination_port)

{

case 80:

printf(“上层协议为HTTP协议n”);

break;

case 21:

printf(“上层协议为FTP协议n”);

break;

case 23:

printf(“上层协议为TELNET协议n”);

break;

case 25:

printf(“上层协议为SMTP协议n”);

break;

case 110:

printf(“上层协议POP3协议n”);

break;

default:

break;

}

printf(“序列码:%un”, sequence);

printf(“确认号:%un”, acknowledgement);

printf(“首部长度:%dn”, header_length);

printf(“保留:%dn”, tcp_protocol->tcp_reserved);

printf(“标记:”);

if(flags &0x08)

printf(“PSH ”);

if(flags &0x10)

printf(“ACK ”);

if(flags &0x02)

printf(“SYN ”);

if(flags &0x20)

编程实现简单的TCP协议分析器

printf(“URG ”);

if(flags &0x01)

printf(“FIN ”);

if(flags &0x04)

printf(“RST ”);

printf(“n”);

printf(“窗口大小:%dn”, windows);

printf(“校验和:%dn”, checksum);

printf(“紧急指针:%dn”, urgent_pointer);} void ip_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content){

struct ip_header *ip_protocol;

/* IP协议变量 */

u_int header_length;

/* 长度 */

u_int offset;

/* 偏移 */

u_char tos;

/* 服务质量 */

u_int16_t checksum;

/* 校验和 */

ip_protocol =(struct ip_header*)(packet_content + 14);

/* 获得IP协议内容 */

checksum = ntohs(ip_protocol->ip_checksum);

/* 获得校验和 */

header_length = ip_protocol->ip_header_length *4;

/* 获得长度 */

tos = ip_protocol->ip_tos;

/* 获得服务质量 */

offset = ntohs(ip_protocol->ip_off);

/* 获得偏移 */ if(ip_protocol->ip_protocol==6)

{

printf(“-----------IP协议

-----------n”);

编程实现简单的TCP协议分析器

printf(“版本号:%dn”, ip_protocol->ip_version);

printf(“首部长度:%dn”, header_length);

printf(“服务质量:%dn”, tos);

printf(“总长度:%dn”, ntohs(ip_protocol->ip_length));

printf(“标识:%dn”, ntohs(ip_protocol->ip_id));

printf(“偏移:%dn”,(offset &0x1fff)*8);

printf(“生存时间:%dn”, ip_protocol->ip_ttl);

printf(“协议类型:%dn”, ip_protocol->ip_protocol);

printf(“上层协议为TCP协议n”);

printf(“校验和:%dn”, checksum);

printf(“源IP地址:%sn”, inet_ntoa(ip_protocol->ip_souce_addre));

/* 获得源IP地址 */

printf(“目的IP地址:%sn”, inet_ntoa(ip_protocol->ip_destination_addre));

/* 获得目的IP地址 */

} } void ethernet_protocol_packet_callback(u_char *packet_header, const u_char *packet_content){ static int packet_number = 1;

/* 数据包个数,静态变量 */ u_short ethernet_type;

/* 以太网类型 */

struct ether_header *ethernet_protocol;struct ip_header *ip_protocol;

/* IP协议变量 */

u_int header_length;

/* 长度 */

u_int offset;

/* 偏移 */

u_char tos;

/* 服务质量 */

u_int16_t checksum;

/* 校验和 */

ip_protocol =(struct ip_header*)(packet_content + 14);

/* 获得IP协议内容 */

checksum = ntohs(ip_protocol->ip_checksum);

*argument, const struct pcap_pkthdr 编程实现简单的TCP协议分析器

/* 获得校验和 */

header_length = ip_protocol->ip_header_length *4;

/* 获得长度 */

tos = ip_protocol->ip_tos;

/* 获得服务质量 */

offset = ntohs(ip_protocol->ip_off);

/* 获得偏移 */

/* 以太网协议变量 */ ethernet_protocol =(struct ether_header*)packet_content;ethernet_type = ntohs(ethernet_protocol->ether_type);/* 获得以太网类型 */ if(ethernet_type==0x0800 && ip_protocol->ip_protocol==6){ u_char *mac_string;

/* 以太网地址 */

printf(“**************************************************n”);

printf(“捕获第%d个TCP网络数据包n”, packet_number);

printf(“捕获时间:n”);

printf(“%s”, ctime((const time_t*)&packet_header->ts.tv_sec));

/* 获得捕获数据包的时间 */

printf(“数据包长度:n”);

printf(“%dn”, packet_header->len);

printf(“--------

以太网协议

--------n”);

/* 获得以太网协议内容 */

printf(“类型:n”);

printf(“%04xn”, ethernet_type);

printf(“源以太网地址: n”);

mac_string = ethernet_protocol->ether_shost;

printf(“%02x:%02x:%02x:%02x:%02x:%02xn”,*mac_string, *(mac_string *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));

/* 获得源以太网地址 */

printf(“目的以太网地址: n”);

mac_string = ethernet_protocol->ether_dhost;

printf(“%02x:%02x:%02x:%02x:%02x:%02xn”, *mac_string, *(mac_string *(mac_string + 2), *(mac_string + 3), *(mac_string + 4), *(mac_string + 5));

/* 获得目的以太网地址 */

ip_protocol_packet_callback(argument, packet_header, packet_content);

+ 1),+ 1), 编程实现简单的TCP协议分析器

packet_number++;

printf(“**************************************************n”);

} } void main(){

pcap_t *pcap_handle;

/* Winpcap句柄 */

char error_content[PCAP_ERRBUF_SIZE];

/* 存储错误信息 */

char *net_interface;

/* 网络接口 */

struct bpf_program bpf_filter;

/* BPF过滤规则 */

char bpf_filter_string[] = “”;

/* 过滤规则字符串 */

bpf_u_int32 net_mask;

/* 掩码 */

bpf_u_int32 net_ip;

/* 网路地址 */

net_interface = pcap_lookupdev(error_content);

/* 获得可用的网络接口 */

pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);

/* 获得网络地址和掩码地址 */

pcap_handle = pcap_open_live(net_interface, BUFSIZ, 1, 1, error_content);

/* 打开网路接口 */

pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);

/* 编译BPF过滤规则 */

pcap_setfilter(pcap_handle, &bpf_filter);

/* 设置过滤规则 */

if(pcap_datalink(pcap_handle)!= DLT_EN10MB)

return;

pcap_loop(pcap_handle,-1, ethernet_protocol_packet_callback, NULL);

/* 注册回调函数,循环捕获网络数据包,利用回调函数来处理每个数据包 */

pcap_close(pcap_handle);

/* 关闭Winpcap操作 */ }

编程实现简单的TCP协议分析器

七、测试数据

本地局域网IP数据包

八、测试情况

程序运行结果图:

编程实现简单的TCP协议分析器

编程实现简单的TCP协议分析器

结 论

通过两周的课程设计,增强了我的实际动手能力,通过实际的编程整合串联了我所学到的知识。另外我还学到了作为编程人员的一些基本素质,这为我毕业后找工作奠定了基础。

通过做TCP协议分析器学习的很多网络编程知识: 1.学会了winpcap网络数据报捕获开发包的使用; 2.绑定网卡函数bind(); 3.数据接受函数recv(); 4.Windows套接字编程;

5.学习了原始套接字编程的基本机制; 6.学习对数据包进行协议分析的基本方法。

通过做TCP协议分析器学习的很多Visual C++ Windows编程知识:

1.学会了Windows常用数据结构的使用;

2.学到了一些用Visual C++ Windows编程的技巧。

编程实现简单的TCP协议分析器

参考文献

[1] 甘玲 邱劲 《面向对象技术与Visual C++ 》 清华大学出版社 [2] 任哲 《MFC Windows 应用程序设计》清华大学出版社 [3] 《计算机网络》 北京:机械工业出版社

[4] 《Visual C++网络通信编程实用案例精选》 人民邮电出版社 [5] 《windows程序设计》 北京大学出版社

《计算机网络课程设计编程实现简单的TCP协议分析器.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
计算机网络课程设计编程实现简单的TCP协议分析器
点击下载文档
相关专题 计算机网络课程设计 分析器 计算机网络 课程设计 计算机网络课程设计 分析器 计算机网络 课程设计
[协议书]相关推荐
    [协议书]热门文章
      下载全文