TCP/IP协议分析-阅读调式IP协议源代码
实验内容:阅读、调试IP协议源代码
姓名:陈春玮
学号:142050121
实验日期:2014.11.25
一、实验目的:
TCP/IP协议簇各功能函数之间的调用过程是协议簇运行的基础,查看TCP/IP协议簇各函数源代码实现及调用关系有助于整体理解协议簇。
实验要求阅读并调通IP协议源代码各函数的相互调用,理解网络报文转发功能这一TCP/IP核心功能的实现方式。
二、实验内容
(一)IP进程实现ipproc.c
structep*ipgetp()这个函数实现用循环法获取一个ip数据报。
if((pip->ip_verlen>>4)!=IP_VERSION)如果IP数据报的版本号不是4,则丢弃报文,接收下一个ip数据包;
if(IP_CLASSD(pip->ip_dst)||IP_CLASSE(pip->ip_dst))如果ip数据首部目的地址是一个E类地址,丢弃报文,接收下一个ip数据包;
if(ifnum!=NI_LOCAL)
if(cksum(pip,IP_HLEN(pip)>>1)) 如果ip数据报不是来自回环接口,则计算首部校验和,如有误,则丢弃报文,接收下一个ip数据包。
prt=rtget(pip->ip_dst,(ifnum==NI_LOCAL));if(prt==NULL){if(gateway)为该报文获取路由,判断该报文是否来自外部接口并要转发到外部接口,若是,则判断该主机是不是网关,不是则丢弃报文,接收下一个ip数据包。
iph2net()将报文首部字节序转换为网络字节序。
Ipdbc()这个函数查看报文是否是一个定向广播的报文,传入ip数据包的输入接口号,以太网帧,该数据包的路由。
Ipredirect()查看是否需要对该报文的路由进行重定向处理,传入ip数据包的输入接口号,以太网帧,该数据包的路由。
(二)IP输出处理ipputp.c
if(pni->ni_state==NIS_DOWN)如果IP数据报的网络接口没有打开,则丢弃该报文并返回syserr
Cksum()计算首部校验和。传入IP数据报和分片长度,之后计算分片相关信息,ipfsend ()函数发送相应的分片,传入发送IP数据包的接口结构,以太网帧,已通过分片发送的数据量,每个分片包含的数据长度,下一个要发送的分片的分片的偏移量。
Ipfhcopy()函数复制原报文的首部,之后处理最后一个分片,调用netwrite()函数发送最后一个分片,传入,ip数据包的接口结构,需要发送的帧,偏移。
(三)IP数据报分片ipfhcopy.用于将原来的数据包首部拷贝到分片数据包上。offindg 为0表示该分片是第一个分片,blkcopy()函数复制报文首部的所有部分。之后复制报文首部和基本首部,计算原IP数据包的首部长度并获取第一个选项的位置i=hlen。之后对原IP数据包的首部选项选择性的复制,otype 获取选项类型,olen获取选项长度。
(四)IP数据报重组处理分片ipreass.c
信号量ipfmutex保证之后的操作是原子操作,firstfree指向空闲分片队列的序号,函数收到一个分片时,遍历分片队列,如果分片队列中分片的描述符与当前分片的描述符不同,则继续遍历,若分片队列中分片的源地址与当前分片的源地址不同,也继续遍历。之后合适的分片入队列。
Ipfjoin()函数用于查看队列中的分片是否到齐。若没有找到合适的分片队列,则为到来的ip分片创建新的分片队列。
(五)IP数据报分片重组ipfcons.c
pep=(structep*)getbuf(Net.lrgpool);为重组报文分配缓冲区,peptmp指向第一个分片,pip指向分片中的每个分片。blkcopy复制报文首部,若分片队列非空则重组分片,dlen,doff分别表示重组时从分片中复制数据的长度和需要复制的数据在分片中的偏移。最后重组完成,释放分片队列。
(六)路由选择rtget.c
Prt指向相关路由表,hv储存目的ip地址的散列值。rtinit()函数用于初始化路由表,信号量Route.ri_mutex保证之后的操作时原子操作,rthash()函数用于计算ip地址的散列值。之后遍历具有相同散列值的链表,查找路由项。并跳过超时的路由,若路由距离可达则找到匹配路由,否则使用默认路由。由于在选择路由时,路由表可能被刷新,所以之后再判断一次路由是否到达。若获得合适的路由则释放信号量,返回路由表的地址。
TCP/IP协议分析-ARP协议源代码修改重编译
实验内容:改进ARP协议源代码并重新编译运行
(一)Arp输入函数arp_in.c
函数首先将首部中的硬件地址类型,协议地址类型和操作字段的字节序转换为本机字节序,然后检查硬件地址类型与接口层定义的硬件地址类型匹不匹配,或协议地址类型是不是ipv4,不是则丢弃;之后查看缓冲区中是否有发送方ip地址的缓冲区表项,有则刷新发送ip对应的硬件地址。Arpadd()用于添加缓冲区中没有的表项,arpqsend()用于发送rap 报文,参数为缓冲区表项。若收到arp请求报文,则构造相应的请求报文,将请求报文中的IP地址作为应答报文中的IP地址,将请求报文中的硬件地址作为应答报文中的目的硬件地址,将本机硬件地址作为应答报文中发送目的硬件地址,转换字节序为网络字节序,计算发送的报文长度,最后发送。
(二)Arp缓冲区维护函数arptimer.c
函数传入时间间隔为参数,为保证数据的一致性,设置disable中断许可标志位,之后遍历表项,当表象是空表项或者其生存时间是永久时,忽略表项。当表项状态为as_pending 时,arp请求报文重传次数加1,若没超过规定的最大重传次数,则设置生存时间为arp_reseng,再次发送。刷新下一个表项。
(三)关于arp攻击
arp_in.c函数中
if(pae=arpfind(SPA(parp),parp->ar_prtype,pni)){
blkcopy(pae->ae_hwa,SHA(parp),pae->ae_hwlen);
pae->ae_ttl=ARP_TIMEOUT;
}
用于判断arp缓冲区中是否存在目的ip地址的缓冲区表项,若不存在则添加相应的缓冲区表项,arp欺骗攻击则是攻击者构造一个合法的arp请求报文,将接收方协议地址填写被攻击的主机的协议地址,物理地址填写攻击者的物理地址,则网络中其他主机的arp缓冲区中都有了一个攻击者物理地址的表项,所有发送给被攻击者的报文都会发给攻击者。或采用arp缓冲区溢出攻击,即构造大量的填有无效地址的arp请求报文,使得一段时间内真正的地址转换表项无法记录在缓冲区内,造成ip无法获得解析。
防止ARP攻击可以采用以下的一些方法:
1.减少过期时间#ndd–set/dev/arp arp_cleanup_interval 60000 #ndd -set /dev/ip ip_ire_flush_interval60000 60000=60000毫秒默认是300000 加快过期时间,并不能避免攻击,但是使得攻击更加困难,带来的影响是在网络中会大量的出现ARP请求和回复。
2.建立静态ARP表这是一种很有效的方法,而且对系统影响不大。缺点是破坏了动态ARP协议。可以建立 08:00:20:ba:a1:f2 08:00:20:ee:de:1f使用arp–ffilename加载进去,这样的ARP映射将不会过期和被新的ARP数据刷新,除非使用arp–d 才能删除。但是一旦合法主机的网卡硬件地址改变,就必须手工刷新这个arp文件。这个方