




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、简单路由器设计与实现(选做)1.实验目的熟悉并掌握路由器的工作原理;熟悉winpcap编程,掌握数据包捕获与发送的方法;在理解ip协议、icmp协议与路由基本工作原理的基础上,完成一个(软件)路由器基本功能的设计与编程实现。2.实验环境Ø 接入局域网的pc机;Ø 操作系统:windows xp, windows 7等;Ø 推荐开发工具:visual studio 2010;Ø 推荐编程语言:c+/ visual c+;Ø 函数库/开发包:winpcap。3.实验内容(1) 学习并掌握winpcap编程:自行完成winpcap教程中的内容,从而掌
2、握winpcap编程。内容包括但不限于:a) 获取设备列表;b) 打开一个适配器并抓包(分组);c) 解析分组;d) 发送分组;学习内容及源程序参见winpcap官方教程:/docs/docs_412/html/group_wpcap_tut.html。(2) 利用winpcap开发包实现简单路由程序,该路由程序应该至少包括以下功能:a) ip数据包捕获和转发;b) arp请求与解析;c) 重新计算ip数据包的头部校验和;d) 处理ip数据包的头部校验和;处理ip数据包的ttl值;e) 静态路由表维护。在下图所示的完了过拓扑结构中,当所开发的路由器程序
3、部署并运行在计算机c上时,它将(作为一个路由器)能够连通两个子网,正确地捕获、转发来自计算机a和计算机b的分组,使得两个子网中的主机能够互相访问图5-1 实验验证环境配置示意图4.实验方式每位同学独立上机编程实验,实验指导教师现场指导。5.参考内容(1) winpcap简介winpcap (windows packet capture)是windows平台下一个免费、公共的网络访问系统。开发winpcap项目的目的在于为win32应用程序提供访问网络底层的能力。它用于windows系统下的直接的网络编程。关于winpcap的介绍请参阅winpcap开发包可以在http:/www.winpcap
4、.org/上下载,winpcap的技术文档可以从/docs/default.htm下载。附录中给出了主要函数的说明文档。(2) winpcap主要函数及功能介绍winpcap部分主要函数及其功能介绍如下:(1).int pcap_findalldevs_ex(char * source, struct pcap_rmtauth * auth, pcap_if_t * alldevs, char * errbuf)函数功能:create a list of network devices that can be opened with pcap
5、_open().参数说明:source:a char* buffer that keeps the 'source localtion', according to the new winpcap syntax. this source will be examined looking for adapters (local or remote) or pcap files,the strings that must be prepended to the 'source' in order to define if we want local/remote a
6、dapters or files is defined in the new source specification syntax .auth:a pointer to a pcap_rmtauth structure. this pointer keeps the information required to authenticate the rpcap connection to the remote host. this parameter is not meaningful in case of a query to the local host: in that case it
7、can be null.alldevs:a 'struct pcap_if_t' pointer, which will be properly allocated inside this function. when the function returns, it is set to point to the first element of the interface list; each element of the list is of type 'struct pcap_if_t'.errbuf: a pointer to a user-alloca
8、ted buffer (of size pcap_errbuf_size) that will contain the error message (in case there is one).返回值:'0' if everything is fine, '-1' if some errors occurred. the list of the devices is returned in the 'alldevs' variable. when the function returns correctly, 'alldevs'
9、cannot be null. in other words, this function returns '-1' also in case the system does not have any interface to list.(2).void pcap_freealldevs_ex(pcap_if_t * alldevsp)函数功能:free an interface list returned by pcap_findalldevs().(3).pcap_t* pcap_open(const char * source, int snaplen, int flag
10、s, int read_timeout, struct pcap_rmtauth * auth, char * errbuf)函数功能:open a generic source in order to capture / send (winpcap only) traffic.参数说明:source:zero-terminated string containing the source name to open. the source name has to include the format prefix according to the new source specificatio
11、n syntax and it cannot be null.on on linux systems with 2.2 or later kernels, a device argument of "any" can be used to capture packets from all interfaces. in order to makes the source syntax easier, please remember that:the adapters returned by the pcap_findalldevs_ex() can be used immed
12、iately by the pcap_open()in case the user wants to pass its own source string to the pcap_open(), the pcap_createsrcstr() helps in creating the correct source identifier.snaplen:length of the packet that has to be retained. for each packet received by the filter, only the first 'snaplen' byt
13、es are stored in the buffer and passed to the user application. for instance, snaplen equal to 100 means that only the first 100 bytes of each packet are stored.flags:keeps several flags that can be needed for capturing packets. the allowed flags are defined in the pcap_open() flags .read_timeout:re
14、ad timeout in milliseconds. the read timeout is used to arrange that the read not necessarily return immediately when a packet is seen, but that it waits for some amount of time to allow more packets to arrive and to read multiple packets from the os kernel in one operation. not all platforms suppor
15、t a read timeout; on platforms that don't, the read timeout is ignored.auth:a pointer to a 'struct pcap_rmtauth' that keeps the information required to authenticate the user on a remote machine. in case this is not a remote capture, this pointer can be set to null.errbuf:a pointer to a u
16、ser-allocated buffer which will contain the error in case this function fails. the pcap_open() and findalldevs() are the only two functions which have this parameter, since they do not have (yet) a pointer to a pcap_t structure, which reserves space for the error string. since these functions do not
17、 have (yet) a pcap_t pointer (the pcap_t pointer is null in case of errors), they need an explicit 'errbuf' variable. 'errbuf' may also be set to warning text when pcap_open_live() succeds; to detect this case the caller should store a zero-length string in 'errbuf' before ca
18、lling pcap_open_live() and display the warning to the user if 'errbuf' is no longer a zero-length string.返回值: a pointer to a 'pcap_t' which can be used as a parameter to the following calls (pcap_compile() and so on) and that specifies an opened winpcap session. in case of probl
19、ems, it returns null and the 'errbuf' variable keeps the error message.(4). int pcap_next_ex(pcap_t * p, struct pcap_pkthdr * pkt_header, const u_char * pkt_data)函数功能:read a packet from an interface or from an offline capture.this function is used to retrieve the next available packet, bypas
20、sing the callback method traditionally provided by libpcap. pcap_next_ex fills the pkt_header and pkt_data parameters (see pcap_handler() with the pointers to the header and to the data of the next captured packet.返回值:the return value can be:1 if the packet has been read without problems0 if the tim
21、eout set with pcap_open_live() has elapsed. in this case pkt_header and pkt_data don't point to a valid packet-1 if an error occurred-2 if eof was reached reading from an offline capture(5). int pcap_compile(pcap_t * p, struct bpf_program * fp, char * str, int optimize, bpf_u_int32 netmask)函数功能:
22、compile a packet filter, converting an high level filtering expression (see filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine.(6). int pcap_setfilter(pcap_t * p, struct bpf_program * fp)函数功能:associate a filter to a capture. 此函数是要和函数pcap_compile()配
23、合使用。(7). int pcap_sendpacket(pcap_t * p, u_char * buf, int size)函数功能: send a raw packet.6.实验步骤6.1 winpcap开发包安装与配置下载、安装winpcap开发包,配置visualstudio 2010开发环境。具体步骤请同学们参阅网上资料自行完成。6.2 用户界面设计(1).首先打开vs2010,新建工程,选择mfc application,输入工程名,点击ok,图5-2点击next,选择dialog based,点击next跳到最后一个页面选择.dlg,点击finish。图5-3图5-4到此为止工
24、程新建完毕,运行会出现以下页面,下面就为这个对话框拖拽控件。图5-5首先将对话框上面的三个控件删除,并拖拽相应的控件得到如下效果:图5-6图5-7其中对话框可在resource view打开,控件在toolbox中可以找到,图5-8其中启动、退出、添加路由、删除路由为button控件,两个空白区为list box,日志、路由表、子网掩码、目的地址、下一跳步为static text,三个输入ip的控件为ip address control,将控件拖拽到相应的位置并且在控件的属性框中修改控件的caption以及id。启动onstart_button退出onstop_button日志idc_stat
25、ic第一个空白区logger_list路由表idc_static第二个空白区router_list子网掩码idc_static子网掩码对应的ip输入区idc_netmask目的地址idc_static目的地址对应的ip输入区idc_ipaddress下一跳步idc_static下一跳步对应的ip输入区idc_nexthop添加路由add_router_button删除路由delete_router_button6.3 代码实现(1). 事件响应函数及主流程控件添加完成后为button添加相应的单击事件并修改单击事件名称,对应关系如下:启动onstartclickedbutton()退出onbn
26、clickedbutton()添加路由onaddrouterbutton()删除路由ondeleterouterbutton()vc程序首先执行程序初始化函数oninitdialog(),在此函数中我们获取了mfc窗体指针。当我们点击“启动”按钮时,程序会执行onstartclickedbutton()函数,此函数流程图如下图所示:图5-9当我们点击结束按钮时程序会执行onbnclickedbutton(),程序自动退出。当程序退出时会触发on_wm_destroy()消息,从而会执行ondestroy()函数,并且程序在执行过程中每隔一段时间会执行ontimer()函数。(2). 主要数据结
27、构和函数声明首先将程序所用变量以及函数复制到vcrouterdlg.cpp文件中:#definemax_if5 / 最大接口数目#pragma pack(1)typedef struct frameheader_t / 帧首部 uchardesmac6; / 目的地址 ucharsrcmac6; / 源地址 ushortframetype; / 帧类型 frameheader_t;typedef struct arpframe_t / arp帧frameheader_tframeheader; / 帧首部 wordhardwaretype; / 硬件类型wordprotocoltype; /
28、协议类型bytehlen; / 硬件地址长度byteplen; / 协议地址长度wordoperation; / 操作值ucharsendha6; / 源mac地址ulongsendip; / 源ip地址ucharrecvha6; / 目的mac地址ulongrecvip; / 目的ip地址 arpframe_t;typedef struct ipheader_t / ip首部bytever_hlen; / 版本+头部长度bytetos; / 服务类型wordtotallen; / 总长度wordid; / 标识wordflag_segment; / 标志+片偏移bytettl; / 生存时间
29、byteprotocol; / 协议wordchecksum; / 头部校验和ulongsrcip; / 源ip地址ulongdstip; / 目的ip地址 ipheader_t;typedef struct icmpheader_t / icmp首部byte type; / 类型byte code; / 代码word checksum; / 校验和word id; / 标识word sequence; / 序列号 icmpheader_t;typedef struct ipframe_t / ip帧frameheader_tframeheader; / 帧首部ipheader_tiphead
30、er; / ip首部 ipframe_t;typedef struct ip_t / 网络地址ulongipaddr; / ip地址ulongipmask; / 子网掩码 ip_t;typedef struct ifinfo_t / 接口信息cstringdevicename; / 设备名cstringdescription; / 设备描述ucharmacaddr6; / mac地址carray <ip_t,ip_t&>ip; / ip地址列表pcap_t*adhandle; / pcap句柄 ifinfo_t;typedef struct sendpacket_t / 发
31、送数据包结构intlen; / 长度bytepktdata2000;/ 数据缓存ulongtargetip; / 目的ip地址uint_ptrn_mtimer; / 定时器uintifno; / 接口序号 sendpacket_t;typedef struct routetable_t / 路由表结构ulongmask; / 子网掩码ulongdstip; / 目的地址ulongnexthop; / 下一跳步uintifno; / 接口序号 routetable_t;typedef struct ip_mac_t / ip-mac地址映射结构ulongipaddr; / ip地址ucharma
32、caddr6; / mac地址 ip_mac_t;/ 全局变量/*/ifinfo_tifinfomax_if; / 接口信息数组intifcount; / 接口个数uint_ptr timercount; / 定时器个数clist <sendpacket_t, sendpacket_t&> sp; / 发送数据包缓存队列clist <ip_mac_t, ip_mac_t&> ip_mac; / ip-mac地址映射列表clist <routetable_t, routetable_t&> routetable; / 路由表cmyrou
33、terdlg *pdlg ; / 对话框指针cmutex mmutex(0,0,0); / 互斥/*/ 全局函数/*/ ip地址转换cstring ipntoa(ulong nipaddr);/ mac地址转换cstring macntoa(uchar *nmacaddr);/ mac地址比较bool cmpmac(uchar *mac1, uchar *mac2);/ mac地址复制void cpymac(uchar *mac1, uchar *mac2);/ mac地址设置void setmac(uchar *mac, uchar ch);/ ip地址查询bool iplookup(ulo
34、ng ipaddr, uchar *p);/ 数据包捕获线程uint capture(pvoid pparam);/ 获取本地接口mac地址线程uint capturelocalarp(pvoid pparam);/ 发送arp请求void arprequest(pcap_t *adhandle, uchar *srcmac, ulong srcip, ulong targetip);/ 查询路由表dword routelookup(uint &ifno, dword desip, clist <routetable_t, routetable_t&> *route
35、table);/ 处理arp数据包void arppacketproc(struct pcap_pkthdr *header, const u_char *pkt_data);/ 处理ip数据包void ippacketproc(ifinfo_t *pifinfo, struct pcap_pkthdr *header, const u_char *pkt_data);/ 处理icmp数据包void icmppacketproc(ifinfo_t *pifinfo, byte type, byte code, const u_char *pkt_data);/ 检查ip数据包头部校验和是否正确
36、int ischecksumright(char * buffer);/ 计算校验和unsigned short checksumcompute(unsigned short *buffer, int size);(3). 函数代码实现/ 获取本地接口mac地址线程uint capturelocalarp(pvoid pparam)intres;struct pcap_pkthdr*header;const u_char*pkt_data;ifinfo_t*pifinfo;arpframe_t*arpframe;cstringdisplaystr;pifinfo = (ifinfo_t *)p
37、param;while (true)sleep(50);res = pcap_next_ex( pifinfo->adhandle , &header, &pkt_data);/ 超时 if (res = 0) continue; if (res > 0)arpframe = (arpframe_t *) (pkt_data);/ 得到本接口的mac地址if (arpframe->frameheader.frametype = htons(0x0806) && (arpframe->operation = htons(0x0002) &a
38、mp;& (arpframe->sendip = pifinfo->ip0.ipaddr) cpymac(pifinfo->macaddr, arpframe->sendha);return 0;void setmac(uchar *mac, uchar ch)for (int i=0; i<6; i+) maci = ch;return;/ 发送arp请求void arprequest(pcap_t *adhandle, uchar *srcmac, ulong srcip, ulong targetip)arpframe_tarpframe;inti;
39、for (i=0; i<6; i+)arpframe.frameheader.desmaci = 255;arpframe.frameheader.srcmaci = srcmaci;arpframe.sendhai = srcmaci;arpframe.recvhai = 0;arpframe.frameheader.frametype = htons(0x0806);arpframe.hardwaretype = htons(0x0001);arpframe.protocoltype = htons(0x0800);arpframe.hlen = 6;arpframe.plen =
40、4;arpframe.operation = htons(0x0001);arpframe.sendip = srcip;arpframe.recvip = targetip; pcap_sendpacket(adhandle, (u_char *) &arpframe, sizeof(arpframe_t);void cpymac(uchar *mac1, uchar *mac2)for (int i=0; i<6; i+) mac1i=mac2i;/ 比较两个mac地址是否相同bool cmpmac(uchar *mac1, uchar *mac2)for (int i=0;
41、 i<6; i+)if (mac1i=mac2i) continue;else return false;return true;/ 把ip地址转换成点分十进制形式cstring ipntoa(ulong nipaddr)charstrbuf50;u_char*p;cstringstr;p = (u_char *) &nipaddr;sprintf_s(strbuf,"%03d.%03d.%03d.%03d", p0, p1, p2, p3);str = strbuf;return str;/ 把mac地址转换成“%02x:%02x:%02x:%02x:%02
42、x:%02x”的格式cstring macntoa(uchar *nmacaddr)charstrbuf50;cstringstr;sprintf_s(strbuf,"%02x:%02x:%02x:%02x:%02x:%02x", nmacaddr0, nmacaddr1, nmacaddr2, nmacaddr3, nmacaddr4, nmacaddr5);str = strbuf;return str;/ 数据包捕获线程uint capture(pvoid pparam)intres;ifinfo_t*pifinfo;struct pcap_pkthdr*header
43、;const u_char*pkt_data;pifinfo = (ifinfo_t *)pparam;/ 开始正式接收并处理帧while (true)res = pcap_next_ex( pifinfo->adhandle, &header, &pkt_data); if (res = 1)frameheader_t*fh;fh = (frameheader_t *) pkt_data;switch (ntohs(fh->frametype)case 0x0806:arpframe_t *arpf;arpf = (arpframe_t *)pkt_data;/t
44、race1("收到arp包 源ip为:%dn", arpf->sendip);/ arp包,转到arp包处理函数arppacketproc(header, pkt_data);break;case 0x0800:ipframe_t *ipf;ipf = (ipframe_t*) pkt_data;/trace1("收到ip包 源ip为:%dn",ipf->ipheader.srcip );/ ip包,转到ip包处理函数ippacketproc(pifinfo, header, pkt_data);break;default: break;el
45、se if (res = 0)/ 超时continue;elseafxmessagebox("pcap_next_ex函数出错!");return 0;/ 处理arp数据包void arppacketproc(struct pcap_pkthdr *header, const u_char *pkt_data)boolflag;arpframe_tarpf;ipframe_t*ipf;sendpacket_tspacket;positionpos, currentpos;ip_mac_tip_mac;ucharmacaddr6;arpf = *(arpframe_t *)p
46、kt_data;if (arpf.operation = ntohs(0x0002)pdlg->logger.insertstring(-1, "收到arp响应包");pdlg->logger.insertstring(-1, (" arp "+(ipntoa(arpf.sendip)+" - "+macntoa(arpf.sendha);/ ipmac地址映射表中已经存在该对应关系if (iplookup(arpf.sendip, macaddr) pdlg->logger.insertstring(-1, &qu
47、ot; 该对应关系已经存在于ipmac地址映射表中");return;elseip_mac.ipaddr = arpf.sendip;memcpy(ip_mac.macaddr, arpf.sendha, 6);/ 将ip-mac映射关系存入表中ip_mac.addhead(ip_mac);/ 日志输出信息pdlg->logger.insertstring(-1, " 将该对应关系存入ipmac地址映射表中");mmutex.lock(infinite);do/ 查看是否能转发缓存中的ip数据报flag = false;/ 没有需要处理的内容if (sp.i
48、sempty() break;/ 遍历转发缓存区pos = sp.getheadposition();for (int i=0; i < sp.getcount(); i+)currentpos = pos;spacket = sp.getnext(pos);if (spacket.targetip = arpf.sendip)ipf = (ipframe_t *) spacket.pktdata;cpymac(ipf->frameheader.desmac, arpf.sendha);for(int t=0; t<6; t+)ipf->frameheader.srcm
49、act = ifinfospacket.ifno.macaddrt;/ 发送ip数据包pcap_sendpacket(ifinfospacket.ifno.adhandle, (u_char *) spacket.pktdata, spacket.len);sp.removeat(currentpos);/ 日志输出信息pdlg->logger.insertstring(-1, " 转发缓存区中目的地址是该mac地址的ip数据包");pdlg->logger.insertstring(-1, (" 发送ip数据包:"+ipntoa(ipf-&
50、gt;ipheader.srcip) + "->" + ipntoa(ipf->ipheader.dstip) + " " + macntoa(ipf->frameheader.srcmac )+"->"+macntoa(ipf->frameheader.desmac);flag = true;break; while(flag);mmutex.unlock();/ 查询ip-mac映射表bool iplookup(ulong ipaddr, uchar *p)ip_mac_tip_mac;positio
51、npos;if (ip_mac.isempty() return false;pos = ip_mac.getheadposition(); for (int i = 0; i<ip_mac.getcount(); i+) ip_mac = ip_mac.getnext(pos);if (ipaddr = ip_mac.ipaddr)for (int j = 0; j < 6; j+)pj = ip_mac.macaddrj;return true;return false;/ 处理ip数据包void ippacketproc(ifinfo_t *pifinfo, struct pcap_pkthdr *header, const u_char *pkt_data)ipframe_t*ipf;sendpacket_tspacket;ipf = (ipframe_t *) pkt_data;pdlg->logger.insertstr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 兰州社区团购合同范本
- 再生资源回收收购合同范本
- 化工储罐出租合同范本
- 加盟艺术培训合同范本
- 债权置换合同范本
- 农土租赁合同范本
- 加工店转让合同范本
- 中介拿钥匙装修合同范本
- 劳务包活合同范本
- 劳务派遣辞退合同范本
- 护理不良事件管理及根因分析
- 人教版道德与法治三年级下册全册课件【完整版】
- Module8Myfuturelife教学设计-2023-2024学年英语外研版九年级下册
- 中职历史教学计划
- NB-T+10499-2021水电站桥式起重机选型设计规范
- 六年级美术下册全册教案(浙美版)
- JT∕T 795-2023 事故汽车修复技术规范
- 2024年安徽中医药高等专科学校单招职业适应性测试题库附答案
- 湘教版二年级下册美术教案
- 天津在津居住情况承诺书
- 2022年中考数学二轮专题复习:二次函数性质综合题
评论
0/150
提交评论