tcp协议TCP报文格式段格式及每个字段含义

一、再谈端口号(一)端口号定义端口号(Port) 标识了一个主机上进行通信的不同的应用程序 ;在 TCP/IP 协议中 , 用 " 源 IP", " 源端口号 “, " 目的 IP”, " 目的端口号 ", " 协议号 " 这样一个五元组来标识一个通信 ( 可以通过 netstat -n 查看 );(二)端口号范围划分1.一共有 2^16 个端口0 - 1023: 知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的,端口号和进程是一一对应的。1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号,例如8080, 就是由操作系统从这个范围分配的。2.认识知名端口号(Well-Know Port Number)有些服务器是非常常用的, 为了使用方便 , 人们约定一些常用的服务器 , 都是用以下这些固定的端口号 :—— ssh 服务器 , 使用 22 端口—— ftp服务器 , 使用 21 端口—— elnet服务器 , 使用 23 端口—— http服务器 , 使用 80 端口—— https服务器 , 使用 443执行此命令 , 可以看到知名端口号。cat /etc/services
我们自己写一个程序使用端口号时, 要避开这些知名端口号。3.端口号和进程就是K-V关系一个进程是否可以 bind 多个端口号? ——可以。端口号:进程=K:V一个端口号是否可以被多个进程bind? ——不可以4.netstatnetstat是一个用来查看网络状态的重要工具!语法 : netstat [ 选项 ]功能 :查看网络状态常用选项 :n 拒绝显示别名,能显示数字的全部转化成数字l 仅列出有在 Listen (监听) 的服务状态,-ntp就是只看established状态p 显示建立相关链接的PID和程序名t (tcp)仅显示tcp相关选项u (udp)仅显示udp相关选项a (all)显示所有选项,默认不显示LISTEN相关通常使用:netstat -nltp(1)示例1: n 拒绝显示别名,能显示数字的全部转化成数字。(2)示例2: l 仅列出有在 Listen (监听) 的服务状态。(3)示例3: p 显示建立相关链接的程序名。5.pidof在查看服务器的进程 id 时非常方便 .语法 : pidof [ 进程名 ]**功能 :**通过进程名 , 查看进程 idUDP 协议UDP 协议端格式二、UDP协议(一)UDP协议端格式1.UDP协议结构前8个字节是 UDP报头;剩下是报文!16位源端口号:自己的进程的端口号16位目的端口号:要访问的目标进程的端口号16位UDP长度:表示整个数据报(UDP首部+UDP数据)的最大长度;就是为了让UDP成为数据报式,而不是流式的。数据报:报文和报文之间有明显边界,因为有16位UDP长度。把一个一个的报文通过UDP长度分开一次接收一个。tcp字节流就需要一直等到读取长度到达encode报头长度才能进行。16位UDP检验和:如果校验和出错,说明数据有问题,就会直接丢弃,暂时不考虑这个。2.报头就是带有位段的结构体3.添加报头的本质,其实就是拷贝对象把对象的成员变量填好,通过sizeof(udp_header)的大小拷贝进二进制,再强转成udp_header(udp_hdr)类型。(二)UDP的特点UDP传输的过程类似于寄信.无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接;不可靠: (不可靠是特点不是缺点,中性词)没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息;(不可靠可理解为:传输过程UDP报文丢失就真的丢失了。优点是:不需要为可靠性做更多的工作——>代码简单,维护简单,效率高等)面向数据报: 不能够灵活的控制读写数据的次数和数量;经典UDP的使用场景:直播(三)面向数据报数据报:报文和报文之间有明显边界,因为有16位UDP长度。应用层交给UDP多长的报文, UDP原样发送, 既不会拆分, 也不会合并;举例:用UDP传输100个字节的数据:如果发送端调用一次sendto, 发送100个字节, 那么接收端也必须调用对应的一次recvfrom, 接收100个字节; 而不能循环调用10次recvfrom, 每次接收10个字节;(四)UDP的缓冲区UDP没有真正意义上的发送缓冲区. 调用sendto会直接交给内核, 由内核将数据传给网络层协议进行后续的传输动作;UDP具有接收缓冲区,但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致(即:UDP报文大概率乱序,因为UDP不保证可靠性); 如果缓冲区满了, 再到达的UDP数据就会被丢弃;UDP的socket既能读,也能写,因为UDP写和读数据的路径是两个,这个概念叫做全双工。(五)UDP使用注意事项我们注意到, UDP协议首部中有一个16位的最大长度,也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部).然而64K在当今的互联网环境下, 是一个非常小的数字.如果我们需要传输的数据超过64K,就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装;这是没办法的。(六)基于UDP的应用层协议NFS: 网络文件系统TFTP: 简单文件传输协议DHCP: 动态主机配置协议BOOTP: 启动协议 ( 用于无盘设备启动 )DNS: 域名解析协议当然 , 也包括你自己写 UDP 程序时自定义的应用层协议三、TCP协议(一)TCP定义TCP全称为“传输控制协议 (Transmission Control Protocol)”,人如其名,要对数据的传输进行一个详细的控制。(二)TCP协议段格式1.如何封装和解包:封装:封装和UDP一样,定义一个 TCP_header 的对象,把报头对象的各个值填上,再把这个对象拷贝到报文的前面即可;解包:用先读取前20字节,读取其中的 4位首部长度, 4位首部长度*4 - 20 = 选项的大小2.如何分用通过“16位目的端口号” 实现向上应用层交付实现分用。3.详细介绍TCP协议段格式TCP报文包含报头和有效载荷。TCP报头包括前2字节和选项。报头是变长的:前20字节是标准长度,选项是变长的。源/目的端口号: 表示数据是从哪个进程来 , 到哪个进程去 ;32位序号/32位确认号 :序号标定一个报文的编号;确认号标定 该确定号之前的报文全部收到 ,保证双向的全双工的确认应答机制。4位TCP报头长度(4位首部长度 ): 表示该 TCP头部有多少个32位bit(单位是4字节);此值是4bit位,则取值范围是0000-1111,即0~15,因为单位是4字节,所以TCP头部最大长度是15 * 4 = 60;因为标准长度有20,所以4位首部长度最少是 20 / 4字节 = 5=0101,即4位首部长度范围是0101-1111,20-60字节,则选项的大小就是0-40字节。6位标志位。4.报文也是有类别的16 位窗口大小: 应答本质就是要包含TCP报头,tcp报头可以有保存server接受能力的属性字段,叫做 16位窗口大小 详解见下面 5.—>(2)16位校验和 : 发送端填充 , CRC 校验 . 接收端校验不通过 , 则认为数据有问题 . 此处的检验和不光包含 TCP 首部 , 也包含TCP 数据部分.(16位检验和是为了验证数据在传输过程有没有问题,有问题就丢掉。暂时不考虑这个属性)16 位紧急指针 : 标识哪部分数据是紧急数据 ;40 字节头部选项 : 暂时忽略 ;ACK: 确认号是否有效PSH: 提示接收端应用程序立刻从 TCP缓冲区把数据读走RST: 对方要求重新建立连接 ; 我们把携带 RST 标识的称为 复位报文段SYN: 请求建立连接 ; 我们把携带SYN标识的称为同步报文段FIN: 通知对方 , 本端要关闭了 , 我们称携带 FIN 标识的为 结束报文段SYN:同步标记位,只要报文是建立链接的请求,SYN需要被设置为1,证明是链接请求的报文(sync的前三个字母)FIN:该报文是一个断开链接的请求报文(finish)ACK:确认标记位,设置为1表示该报文不仅仅是对历史报文的确认,同时也可以携带要发送的数据,一般在大部分正式通信的情况下ACK都是1。PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走解释:之前我们是通过阻塞式调用read函数来读取数据,现在是通知以后再调用read,后者效率更高。示例说明:假设接收缓冲区大小是100字节,超过了20字节会向上应用层通知来read,20叫接收数据的低水位线。当接收缓冲区内数据超过了20字节,PSH会让服务器操作系统通知上层已有数据,快来read。URG:紧急指针标记位。作用:该报文忽略序号,被上层直接读取处理。(该报文叫紧急指针报文)详情见三—>2—>(3)RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段。若最后的ACK丢失,则客户端不知道仍认为建立好连接了,则会继续发消息;服务器在未收到ACK时也意识到了这种问题,为了避免这种情况,服务器在未收到ACK时会连接重置,重新发送SYN+ACK应答,同时也把RST置为1!5.32位序号保证按序到达——URG(1)32位序号保证按序到达到达:报文在发送的时候,是可能乱序到达的。这是不可靠的一种。需要让我们的报文进行按序到达,如何做到?——32位序号保证按序到达。为报文标序号,接收缓冲区收到后排序即可。(2)URG紧急指针标记位与紧急指针:如果数据是必须在TCP中进行按序到达的话,也就是说如果有一些数据优先级更高,但是序号较晚,无法做到数据被有限紧急处理!解决方案:使用 URG紧急指针标记位, URG标记为1,将优先级更高的报文忽略序号,被上层直接读取处理。(该报文叫紧急指针报文)16位紧急指针:指向紧急指针报文的偏移量。紧急指针报文只能有一个字节!(3)URG应用场景——用来 获取服务器/主机状态客户端向服务器发数据,服务器可能因某种原因(例如内存不足)而无法接收消息或接收消息缓慢,这种情况下客户端想获知服务器的状态,就发送报文 URG紧急指针标记位 标为1,此时server在非常困难的情况下依旧优先接收了指向的一字节,在服务器内部通过已设置的某种逻辑得出一个状态码20(假设),通过 URG紧急指针标记位 把指向的一字节返回给客户端,客户端收到20状态码得知服务器无法正常工作原因是“内存不足”,再通知工作人员即可。6.可靠性问题(1)什么是不可靠:丢包,乱序,校验失败。(2)怎么确认一个报文是丢了还是没丢? ?(确认应答机制)答:我们如果收到了应答,我们确认是没丢,否则就是不确定。可靠性是指我们发出去的报文得到了对方应答是可靠的,没被应答的不能保证可靠。详细解释:我们发出去的消息,我们如何得知对方是否收到?——只要得到对方的应答就意味着我刚刚发的消息对方100%收到了!在长距离交互的时候,永远有一条最新的数据是没有应答的,所以没有百分之百可靠的协议!!但是可以做到局部百分之百可靠。但是:只要发送的消息有对应的应答,我们就认为我们发送的消息,对方是收到的! !确认应答机制保证了数据能被对方收到的问题。7.确认应答(ACK)机制(1)32位序号/32位确认号建立一个共识: tcp进行通信的时候,发送出去的报文一定会携带tcp报头!解释下图:客户端发送一个有效载荷时一定是携带tcp报头的,并且数据都已经填好。假设随机生成的起始序号是1, 客户端发给服务器的整个报头+报文大小1000字节,则他占了1~1000序号,则32位序号就是1。服务器收到后为了应答客户端,则他会回复32位确认号是1001,它表示接收方已经收到了字节序号为 [1, 1000] 的数据,现在期望你发送字节序号为 1001 以及以后的数据。32位序号/32位确认号:序号标定一个报文的编号;确认号标定 该确定号之前的报文全部收到,之后的报文从该确定好下一个序号开始发 ,保证双向的全双工的确认应答机制。例:服务器收到6个报文,32位序号分别是1,2,3,5,6,7,响应时返回给客户端的确认序号应该填4。解释:确认号是为了告诉客户端特定序号之前的报文全部收到,因为这里没收到4号报文,所以填4是告诉客户端4之前的报文全部收到,4没收到,客户端要从4号开始重新发。(2)为什么TCP报头有32位序号和32位确认号两组序号?常考因为TCP协议是全双工的,我在给你发消息的同时,我也可以收消息。解释:如果服务器想给你应答(填充确认序号),并且同时给你发消息(携带自己的序号)呢?——客户端给服务器发送“你吃饭了吗?”(填充32位序号),服务器给客户端发送应答“我吃饭了”(填充32位确认序号),同时发出“那你吃饭了吗?”(填充自己的32位序号)客户端用序号和对方的确认序号保证了从左向右的可靠性,服务器用自己的序号和对方的确认序号保证了从右向左的可靠性。这样保证了双向的全双工的确认应答机制。(3)TCP 将每个字节的数据都进行了编号,即为序列号。每一个 ACK 都带有对应的确认序列号 , 意思是告诉发送者 , 我已经收到了哪些数据 ; 下一次你从哪里开始发 .8.tcp的发送和接收缓冲区(1)tcp有发送和接收缓冲区IO类函数.本质其实都是拷贝函数我们用write/send函数把数据拷贝到内核缓冲区后,tcp会在合适时候进行发送。内核缓冲区的数据什么时候发,发多少,出错了怎么办,要不要添加提高效率的策略——是由OS内的TCP自主决定的,所以TCP叫做传输控制协议!上图可知,读写缓冲区用一个文件描述符业互不影响,可以说明TCP通信是全双工的!(2)16位窗口大小——流量控制策略在客户端向服务器发送数据包时,如果发送的太快了,导致server来不及接收怎么办?——需要让client知道server的接受能力!1.哪一个指标表示 server的接受能力呢? ——接收缓冲区剩余空间的大小!2. client怎么知道? ? ——发送都会有应答!应答本质就是要包含TCP报头,tcp报头可以有保存server接收能力的属性字段,叫做16位窗口大小。3.server给client发报文,填充的窗口大小,填充的是自己的接收缓冲区剩余空间大小。4. client——>server, server——> client,两个方向都是一样的总结:双方的发送缓冲区基于得知对方接收缓冲区接收能力的条件下进行数据通信,根据对方每次应答中不断更新的窗口大小定期向对方发送合适的数据大小,这种策略就叫做流量控制策略。流量控制策略是双向的!5.这个流量控制策略通过16位窗口大小保存接收能力的属性字段,那第一次客户端向服务器发数据时怎么得知服务器的接收能力呢?三次握手期间不光建立链接,还有就是交换信息 信息就包含了向对端告知自己的接收能力。(3)tcp正文长度由应用层决定tcp流式服务,所以没必要考虑正文长度,正文长度是需要应用层自己定协议的,比如我们写的encode和decode对整个序列化之后的字符串 9\r\n100 + 200\r\n 进行提取长度!四、连接管理机制(一)四次挥手在正常情况下,TCP 要经过三次握手建立连接,四次挥手断开连接。accept和三次握手没关系,只是把已经完成的三次握手提上来。四次挥手:一方向另一方发送FIN断开连接请求,对方ACK应答,对方同理,一个close对应一对挥手,共4次挥手。(特殊情况三次挥手:客户端向服务器发送FIN断开连接请求,对方ACK应答并且正好FIN置1也想断开,客户端在发送第三次ACK,这就是三次)。(二)四次挥手状态(包括握手)1.服务端状态转化:[CLOSED -> LISTEN] 服务器端调用 listen 后进入 LISTEN 状态 , 等待客户端连接 ;[LISTEN -> SYN_RCVD] 一旦监听到连接请求 ( 同步报文段 ), 就将该连接放入内核等待队列中 , 并向客户端发送SYN 确认报文 .[SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文 , 就进入 ESTABLISHED 状态 , 可以进行读写数据了.[ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接 (调用close), 服务器会收到结束报文段, 服务器返回确认报文段ACK并进入CLOSE_WAIT;[CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK状态, 等待最后一个ACK到来(这个ACK是客户端确认收到了FIN)[LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK, 彻底关闭连接。2.客户端状态转化:[CLOSED -> SYN_SENT] 客户端调用 connect, 发送同步报文段 ;[SYN_SENT -> ESTABLISHED] connect 调用成功 , 则进入 ESTABLISHED 状态 , 开始读写数据 ;[ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时, 向服务器发送结束报文段, 同时进入FIN_WAIT_1;[FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段;[FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出LAST_ACK;[TIME_WAIT -> CLOSED] 客户端要等待一个2MSL(Max Segment Life, 报文最大生存时间)的时间, 才会进入CLOSED状态。(1)CLOSE_WAIT 半关闭状态无论是否accept,客户端只要close关闭,但服务器未close关闭,服务器一方就一直是 CLOSE_WAIT 状态(一方close,另一方未close,即半关闭状态):(2)TIME _WAIT连接保持的状态下直接关闭服务器,服务器就成了主动关闭的一方,主动关闭的一方最终就会进入 TIME _WAIT(4次挥手已完成),设置一段时间,过完这一段时间连接就会自动关闭。设置TIME _WAIT一段时间的意义:①保证最后一个ACK尽可能传输成功:若在这个设置合理的时间段内,客户端没有收到服务器的重传FIN,则认为服务器收到了自己的ACK应答;若在这个设置合理的时间段内,客户端收到服务器的重传FIN,则认为刚刚传出的ACK确认应答丢失了,就需要重传ACK;②这一段时间还可以保证让历史发送的数据在网络中消散,即尽可能被对方收到。MSL:最大传输时间,来回就是2个MSLTCP 协议规定 , 主动关闭连接的一方要处于 TIME_ WAIT 状态 , 等待两个 MSL(maximum segment lifetime) 的时间后才能回到CLOSED 状态 .我们使用 Ctrl-C 终止了 server, 所以 server 是主动关闭连接的一方 , 在 TIME_WAIT 期间仍然不能再次监听同样的server 端口 ;MSL 在 RFC1122 中规定为两分钟 , 但是各操作系统的实现不同 , 在 Centos7 上默认配置的值是 60s;可以通过 cat /proc/sys/net/ipv4/tcp_fin_timeout 查看 msl 的值 ;为什么是TIME_WAIT的时间是2MSL?MSL是TCP报文的最大生存时间, 因此TIME_WAIT持续存在2MSL的话就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启, 可能会收到来自上一个进程的迟到的数据, 但是这种数据很可能是错误的);同时也是在理论上保证最后一个报文可靠到达(假设最后一个ACK丢失, 那么服务器会再重发一个FIN. 这时虽然客户端的进程不在了, 但是TCP连接还在, 仍然可以重发LAST_ACK);解决TIME_WAIT状态引起的bind失败的方法(作业)平时我们8080断开后bind不成功就换8081,原因就是:客户端主动断开连接后进入TIME_WAIT状态,TIME_WAIT状态期间仍会保持一个名存实亡的不会再被使用的连接,但这个连接依旧持有客户端的IP和端口,其他进程想绑定就无法绑定,这是操作系统的默认行为在server的TCP连接没有完全断开之前不允许重新监听, 某些情况下可能是不合理的:假设:淘宝狂欢节,服务器需要处理非常大量的客户端的连接(每个连接的生存时间可能很短, 但是每秒都有很大数量的客户端来请求).这个时候如果由服务器端崩溃主动关闭连接, 就会产生大量TIME_WAIT连接.由于我们的请求量很大, 就可能导致TIME_WAIT的连接数很多, 每个连接都会占用一个通信五元组(源ip, 源端口, 目的ip, 目的端口, 协议)。其中服务器的ip和端口和协议是固定的. 如果新来的客户端请求的ip和端口号就是已经TIME_WAIT服务器ip和端口号,就会失败.函数 setsockopt 崩溃时可以重启用 setsockopt() 设置 socket 描述符的 选项 SO_REUSEADDR 为 1, 表示允许创建端口号相同但IP地址不同的多个 socket描述符。int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);
sockfd:被设置的套接字文件描述符。level:设置 SOL_SOCKET 层。optname:设置的名字,一般用SO_REUSEADDR。optval:值 optlen:长度
(三)listen的第2个参数——backloglist的第二个参数叫backlog,叫做底层的全连接队列的长度,算法是: n+1, (n是用户传入的值)表示在不accept的情况你最多能够维护多少个链接。例如传2,就表示在不accept的情况最多能够维护3个链接,剩下的客户端请求的连接以半连接保持,当有全连接退出时,这个半连接才会变成全连接。全连接维护的意义!1.为什么需要排队?可以让我们的服务器在有闲置的情况下,通过accept从底层拿去链接,进行链接处理!相当于是池化技术,形成了一个“链接池(缓冲池)”。2.队列为什么不能太长?①太长影响客户体验②太长过于占用系统资源,反而可能导致服务器效率低下。不如把维护长链
实验一:Wireshark 抓包工具使用一、实验目的学习 Wireshark 抓包工具的使用了解 Wireshark 抓包工具的功能通过学习,进一步理解协议及网络体系结构思想二、实验内容使用 Wireshark,并学习使用它进行网络包分析。三、实验原理Wireshark 是网络包分析工具;网络包分析工具的主要作用是尝试捕获网络包,并尝试显示包的尽可能详细的情况。Wireshark 常见的应用如下:网络管理员用来解决网络问题网络安全工程师用来检测安全隐患开发人员用来测试协议执行情况这里,我们通过 Wireshark 来学习常见的网络协议。四、实验过程包含了从安装 Wireshark 开始到使用 Wireshark 观察一些现象的过程:4.1 下载 WiresharkWireshark 的官方网站是:https://www.wireshark.org/,下载地址是 https://2.na.dl.wireshark.org/win64/Wireshark-win64-3.4.6.exe4.2 准备工作再 Powershell 中输入 ipconfig 查询本机的 IP 信息:在同局域网下打开另一台设备,启动一个服务器:查看局域网内的这台设备的 IP 地址:可以得到的信息汇总如下:机器IP(v4) 地址子网掩码默认网关主机192.168.3.2255.255.255.0192.168.3.1服务器192.168.3.71255.255.255.0192.168.3.1因为只需要这些信息,所以直接在 Powershell 中获取;需要更详细的信息也可以通过网络适配器选项中来获得。接下来使用 Wireshark 捕获两者之间的通讯数据包,并且进行分析。4.3 启动 Wireshark首先需要先选择监听的网络设备:然后,就可以开始捕获以太网的通信数据包:接下来,可以进行捕获通过它的特定报文,并且分析内容。4.4 TCP 握手浏览器访问上面查询到的服务器的地址 http://192.168.3.71,并且在 Wireshark 中设定限制条件(过滤器) ip.src == 192.168.3.71 or ip.dst == 192.168.3.71 来只捕获来自这两个 IP 地址之间的通信。高亮的部分就是 TCP 的三次握手。4.5 TCP 报文分析示例这是上述三次握手过程中的第二次握手的报文的详细信息:项目信息说明源端口80服务器的 HTTP 默认端口,服务确实开在 80 端口上目的端口61577用户浏览器当前开启的用于和服务器通信的端口TCP 段长度0该报文不携带数据Sequence 数字0Seq=0Acknowledge 数字1期望收到的下一个报文满足 Seq=1首部长度32 bytes (8)8 * 4B = 32 bytes标志0x012SYN 和 ACK 位为 1校验和0x5426校验和为 0x5426,未验证http://www.biyezuopin.vip4.6 HTTP 报文分析在 TCP 握手完成之后,服务器将使用 HTTP 协议传输数据到浏览器;我们在紧接着握手完成后面的位置找到了使用 HTTP 协议传输的数据包;可以打开查看其详细信息:内容信息GET / HTTP/1.1操作类型:GET;遵循了 HTTP 1.1 版本的协议Host: 192.168.3.71主机名:192.168.3.71;当绑定域名的场合下会是主机的域名Connection: keep-alive连接类型是保持持久连接User-Agent: ...用户的客户端信息;这里有个 Mozilla/5.0 (Windows NT 10.0 ...) 说明是运行在 Windows 10 上的火狐浏览器…………HTTP 头能塞的东西还挺多的,这里就不全部说明了;当然,这里所包含的项目也未必完整。五、思考题网络工程师能通过 Wireshark 做哪些工作?检查网络协议的执行情况排查网络故障,解决网络问题网络攻防,检测网络安全隐患实验二:WinPcap 编程系统环境开发环境Windows 10 Pro 21H1CLion 2021.1; CMake 3.19; tdm-gcc 9.3; NpCap SDK 1.07http://www.biyezuopin.vip一、实验目的了解 NpCap 架构和运行逻辑学习使用 NpCap SDK 进行编程二、实验内容通过学习 NpCap SDK,编写一个网络抓包程序三、实验原理本实验主要基于 NpCap 完成,所以这里主要是关于 NpCap 的介绍:3.1 NpCap 概述WinPcap 是一个基于 Win32 平台的,用于捕获网络数据包并进行分析的开源库;在 Linux 上也有对应的 LibPcap;目前 WinPcap 已经处于无人维护的状态,对于 Windows 10 有更新的且目前有人维护的开源项目 NpCap。大多数网络应用程序通过被广泛使用的操作系统元件来访问网络,比如 sockets——这是一种简单的实现方式,因为操作系统已经妥善处理了底层具体实现细节(比如协议处理,封装数据包等等工作),并且提供了一个与读写文件类似的,令人熟悉的接口;但是有些时候,这种“简单的实现方式”并不能满足需求,因为有些应用程序需要直接访问网络中的数据包:也就是说原始数据包——即没有被操作系统利用网络协议处理过的数据包。而 WinPcap/NpCap 则为 Win32 应用程序提供了这样的接口:捕获原始数据包;无论它是发往某台机器的,还是在其他设备(共享媒介)上进行交换的在数据包发送给某应用程序前,根据指定的规则过滤数据包将原始数据包通过网络发送出去收集并统计网络流量信息SDK 提供的这些功能需要借助运行在 Win32 内核中的网络设备驱动程序来实现;在安装完成驱动之后,SDK 将这些功能作为一个接口表现出来以供使用。3.2 要使用的接口以下介绍了实现后文提到的 demo 所需要使用的 NpCap API 的简单介绍:3.2.1 pcap_findalldevsNpCap 提供了 pcap_findalldevs_ex 和 pcap_findalldevs 函数来获取计算机上的网络接口设备的列表;此函数会为传入的 pcap_if_t 赋值——该类型是一个表示了设备列表的链表头;每一个这样的节点都包含了 name 和 description 域来描述设备。除此之外,pcap_if_t 结构体还包含了一个 pcap_addr 结构体;后者包含了一个地址列表、一个掩码列表、一个广播地址列表和一个目的地址的列表;此外,pcap_findalldevs_ex 还能返回远程适配器信息和一个位于所给的本地文件夹的 pcap 文件列表。3.2.2 pcap_open用来打开一个适配器,实际调用的是 pcap_open_live;它接受五个参数:name:适配器的名称(GUID)snaplen:制定要捕获数据包中的哪些部分。在一些操作系统中 (比如 xBSD 和 Win32),驱动可以被配置成只捕获数据包的初始化部分:这样可以减少应用程序间复制数据的量,从而提高捕获效率;本次实验中,将值定为 65535,比能遇到的最大的 MTU 还要大,因此总能收到完整的数据包。flags:主要的意义是其中包含的混杂模式开关;一般情况下,适配器只接收发给它自己的数据包, 而那些在其他机器之间通讯的数据包,将会被丢弃。但混杂模式将会捕获所有的数据包——因为我们需要捕获其他适配器的数据包,所以需要打开这个开关。to_ms:指定读取数据的超时时间,以毫秒计;在适配器上使用其他 API 进行读取操作的时候,这些函数会在这里设定的时间内响应——即使没有数据包或者捕获失败了;在统计模式下,to_ms 还可以用来定义统计的时间间隔:设置为 0 说明没有超时——如果没有数据包到达,则永远不返回;对应的还有 -1:读操作立刻返回。errbuf:用于存储错误信息字符串的缓冲区该函数返回一个 pcap_t 类型的 handle。3.2.3 pcap_loopAPI 函数 pcap_loop 和 pcap_dispatch 都用来在打开的适配器中捕获数据包;但是前者会已知捕获直到捕获到的数据包数量达到要求数量,而后者在到达了前面 API 设定的超时时间之后就会返回(尽管这得不到保证);前者会在一小段时间内阻塞网络的应用,故一般项目都会使用后者作为读取数据包的函数;虽然在本次实验中,使用前者就够了。这两个函数都有一个回调函数;这个回调函数会在这两个函数捕获到数据包的时候被调用,用来处理捕获到的数据包;这个回调函数需要遵顼特定的格式。但是需要注意的是我们无法发现 CRC 冗余校验码——因为帧到达适配器之后,会经过校验确认的过程;这个过程成功,则适配器会删除 CRC;否则,大多数适配器会删除整个包,因此无法被 NpCap 确认到。3.2.4 pcap_datalink用于对 MAC 层进行了检测,以确保在处理一个以太网络,确保 MAC 首部是 14 位的。IP 数据包的首部就位于 MAC 首部的后面,将从 IP 数据包的首部解析到源 IP 地址和目的 IP 地址。3.2.5 pcap_compile & pcap_setfilter用来设置过滤器,以避免处理一些无用的包,提高包处理的效率。在本次实验中我们需要将过滤器字符串设置成 ip and udp,使得我们传入的回调只处理基于 IPv4 的 UDP 数据包;大大简化了解析过程和回调函数的调用次数。3.3 其他的补充处理 UDP 数据包的首部时存在一些困难:因为 IP 数据包的首部的长度并不是固定的,但是可以通过 IP 数据包的 length 域来得到它的长度;一旦知道了 UDP 首部的位置,就能解析到源端口和目的端口。四、实验过程从安装 NpCap 到运行 NpCap 示例程序的全部过程;4.1 安装 NpCapNpCap 是 WinPcap for Windows 10;它的官方下载页面是 Npcap: Windows Packet Capture Library & Driver (nmap.org);在这里我们需要下载:NpCap 内核驱动:Npcap 1.31 installerNpCap SDK 文件:Npcap SDK 1.07安装完成驱动后,再在 IDE 中为项目配置导入 NpCap SDK 文件。NpCap SDK 文件包中包括了使用 NpCap 实现的基本功能的 demo。4.2 使用 NpCap 的功能项目的文件结构如下:CMake target: if_list udp_dump basic_dump_ex
(root)
├ module
│ └ (NpCap Library files)
NpCap SDK 库文件
├ src
│ ├ basic_dump_ex.c
目标 basic_dump_ex 的源文件
│ ├ if_list.c
目标 if_list 的源文件
│ └ udp_dump.c
目标 udp_dump 的源文件
└ CMakeList.txt
CMake 项目定义文件
这些使用 NpCap 功能的 demo 的实现代码都位于:https://github.com/ma-hunter/cn_exp五、实验结果上述代码包括的,使用 NpCap 实现的几项基本功能的运行结果(非截图)。5.1 读取网络设备列表使用 CMake,构建并运行上述项目中的目标 if_list:"D:\Program Files\JetBrains\Toolbox\apps\CLion\ch-0\211.6693.114\bin\cmake\win\bin\cmake.exe" --build D:\Workspaces\CLion\cn_exp\cmake-build-debug --target if_list -- -j 4
Scanning dependencies of target if_list
[ 50%] Building C object CMakeFiles/if_list.dir/src/if_list.c.obj
[100%] Linking C executable if_list.exe
[100%] Built target if_list
http://www.biyezuopin.vip
构建已完成
运行结果如下:D:\Workspaces\CLion\cn_exp\cmake-build-debug\if_list.exe \Device\NPF_{5C8B26D4-9439-4304-B8FB-48A81CB33CF9}
Description: WAN Miniport (Network Monitor)
Loopback: no
\Device\NPF_{C21F9683-BA8A-4AFE-827A-166030BB1466}
Description: WAN Miniport (IPv6)
Loopback: no
\Device\NPF_{1C99E263-4855-4786-97ED-ECAC30A11761}
Description: WAN Miniport (IP)
Loopback: no
\Device\NPF_{1A386F2B-3A3E-49A7-B899-2629C46C4FB3}
Description: Hyper-V Virtual Ethernet Adapter #2
Loopback: no
Address Family: #23
Address Family Name: AF_INET6
Address Family: #2
Address Family Name: AF_INET
Address: 172.26.112.1
Netmask: 0.240.255.255
Broadcast Address: 255.31.112.1
\Device\NPF_{A30B9DA2-E755-4DF6-8BD4-010B6590B072}
Description: Hyper-V Virtual Ethernet Adapter
Loopback: no
Address Family: #23
Address Family Name: AF_INET6
Address Family: #2
Address Family Name: AF_INET
Address: 172.26.0.1
Netmask: 0.240.255.255
Broadcast Address: 255.31.0.1
\Device\NPF_{21EAB23F-F3E5-48E0-B370-35B69F40B833}
Description: Bluetooth Device (Personal Area Network) #3
Loopback: no
Address Family: #23
Address Family Name: AF_INET6
Address Family: #2
Address Family Name: AF_INET
Address: 169.254.62.143
Netmask: 0.0.255.255
Broadcast Address: 255.255.62.143
\Device\NPF_{5CCBE082-6FB3-4754-B27A-3659F98979BE}
Description: Realtek RTL8188EU Wireless LAN 802.11n USB 2.0 Network Adapter
Loopback: no
Address Family: #23
Address Family Name: AF_INET6
Address Family: #2
Address Family Name: AF_INET
Address: 169.254.125.212
Netmask: 0.0.255.255
Broadcast Address: 255.255.125.212
\Device\NPF_{E919BE86-5601-4998-B187-2C629DE1F9B9}
Description: Microsoft Wi-Fi Direct Virtual Adapter #2
Loopback: no
Address Family: #23
Address Family Name: AF_INET6
Address Family: #2
Address Family Name: AF_INET
Address: 169.254.194.126
Netmask: 0.0.255.255
Broadcast Address: 255.255.194.126
\Device\NPF_{FF7337C5-5DA3-4AF4-8C55-5A066C578D65}
Description: Microsoft Wi-Fi Direct Virtual Adapter
Loopback: no
Address Family: #23
Address Family Name: AF_INET6
Address Family: #2
Address Family Name: AF_INET
Address: 169.254.180.74
Netmask: 0.0.255.255
Broadcast Address: 255.255.180.74
\Device\NPF_{43524049-AA60-4F6E-A89E-8AE5BA1EAA93}
Description: Realtek PCIe GbE Family Controller
Loopback: no
Address Family: #23
Address Family Name: AF_INET6
Address Family: #2
Address Family Name: AF_INET
Address: 192.168.3.2
Netmask: 0.255.255.255
Broadcast Address: 255.168.3.2
\Device\NPF_Loopback
Description: Adapter for loopback traffic capture
Loopback: yes
进程已结束,退出代码为 0
于此同时可以看到控制面板下的网络适配器页面;可以看到基本的适配器信息是一致的:我们的 demo 输出的更多是因为包含了一些被操作系统用户级别隐藏的接口。5.2 打开设别并抓包监听使用 CMake,构建并运行上述项目中的目标 basic_dump_ex:"D:\Program Files\JetBrains\Toolbox\apps\CLion\ch-0\211.6693.114\bin\cmake\win\bin\cmake.exe" --build D:\Workspaces\CLion\cn_exp\cmake-build-debug --target basic_dump_ex -- -j 4
Scanning dependencies of target basic_dump_ex
[ 50%] Building C object CMakeFiles/basic_dump_ex.dir/src/basic_dump_ex.c.obj
[100%] Linking C executable basic_dump_ex.exe
[100%] Built target basic_dump_ex
构建已完成
运行结果如下:D:\Workspaces\CLion\cn_exp\cmake-build-debug\basic_dump_ex.exe
1. \Device\NPF_{5C8B26D4-9439-4304-B8FB-48A81CB33CF9} (WAN Miniport (Network Monitor))
2. \Device\NPF_{C21F9683-BA8A-4AFE-827A-166030BB1466} (WAN Miniport (IPv6))
3. \Device\NPF_{1C99E263-4855-4786-97ED-ECAC30A11761} (WAN Miniport (IP))
4. \Device\NPF_{1A386F2B-3A3E-49A7-B899-2629C46C4FB3} (Hyper-V Virtual Ethernet Adapter #2)
5. \Device\NPF_{A30B9DA2-E755-4DF6-8BD4-010B6590B072} (Hyper-V Virtual Ethernet Adapter)
6. \Device\NPF_{21EAB23F-F3E5-48E0-B370-35B69F40B833} (Bluetooth Device (Personal Area Network) #3)
7. \Device\NPF_{5CCBE082-6FB3-4754-B27A-3659F98979BE} (Realtek RTL8188EU Wireless LAN 802.11n USB 2.0 Network Adapter)
8. \Device\NPF_{E919BE86-5601-4998-B187-2C629DE1F9B9} (Microsoft Wi-Fi Direct Virtual Adapter #2)
9. \Device\NPF_{FF7337C5-5DA3-4AF4-8C55-5A066C578D65} (Microsoft Wi-Fi Direct Virtual Adapter)
10. \Device\NPF_{43524049-AA60-4F6E-A89E-8AE5BA1EAA93} (Realtek PCIe GbE Family Controller)
11. \Device\NPF_Loopback (Adapter for loopback traffic capture)
Enter the interface number (1-11):10
listening on Realtek PCIe GbE Family Controller...
13:36:31,027242 len:208
13:36:31,068904 len:1071
13:36:31,122063 len:54
13:36:31,423026 len:60
13:36:31,423094 len:54
13:36:31,750427 len:336
13:36:31,750466 len:320
13:36:31,782177 len:66
程序将会运行到被外部中断阻止后才会停止运行。5.3 捕获 UDP 包并分析使用 CMake,构建并运行上述项目中的目标 basic_dump_ex:"D:\Program Files\JetBrains\Toolbox\apps\CLion\ch-0\211.6693.114\bin\cmake\win\bin\cmake.exe" --build D:\Workspaces\CLion\cn_exp\cmake-build-debug --target udp_dump -- -j 4
[100%] Built target udp_dump
构建已完成
运行结果如下:D:\Workspaces\CLion\cn_exp\cmake-build-debug\udp_dump.exe
1. \Device\NPF_{5C8B26D4-9439-4304-B8FB-48A81CB33CF9} (WAN Miniport (Network Monitor))
2. \Device\NPF_{C21F9683-BA8A-4AFE-827A-166030BB1466} (WAN Miniport (IPv6))
3. \Device\NPF_{1C99E263-4855-4786-97ED-ECAC30A11761} (WAN Miniport (IP))
4. \Device\NPF_{1A386F2B-3A3E-49A7-B899-2629C46C4FB3} (Hyper-V Virtual Ethernet Adapter #2)
5. \Device\NPF_{A30B9DA2-E755-4DF6-8BD4-010B6590B072} (Hyper-V Virtual Ethernet Adapter)
6. \Device\NPF_{21EAB23F-F3E5-48E0-B370-35B69F40B833} (Bluetooth Device (Personal Area Network) #3)
7. \Device\NPF_{5CCBE082-6FB3-4754-B27A-3659F98979BE} (Realtek RTL8188EU Wireless LAN 802.11n USB 2.0 Network Adapter)
8. \Device\NPF_{E919BE86-5601-4998-B187-2C629DE1F9B9} (Microsoft Wi-Fi Direct Virtual Adapter #2)
9. \Device\NPF_{FF7337C5-5DA3-4AF4-8C55-5A066C578D65} (Microsoft Wi-Fi Direct Virtual Adapter)
10. \Device\NPF_{43524049-AA60-4F6E-A89E-8AE5BA1EAA93} (Realtek PCIe GbE Family Controller)
11. \Device\NPF_Loopback (Adapter for loopback traffic capture)
Enter the interface number (1-11):10
listening on Realtek PCIe GbE Family Controller...
13:38:26.314222 len:181 192.168.3.2.7726 -> 180.97.33.12.8829
13:38:26.339699 len:163 180.97.33.12.8829 -> 192.168.3.2.7726
13:38:28.517235 len:361 223.166.151.86.8000 -> 192.168.3.2.4017
13:38:28.517526 len:97 192.168.3.2.4017 -> 223.166.151.86.8000
13:38:29.100916 len:82 192.168.3.2.60173 -> 192.168.3.1.53
13:38:29.151404 len:149 192.168.3.1.53 -> 192.168.3.2.60173
13:38:30.577642 len:129 223.166.151.86.8000 -> 192.168.3.2.4017
程序将会运行到被外部中断阻止后才会停止运行。六、思考题WINPCAP 是否能实现服务质量的控制?不能。WinPcap 可以独立地通过主机协议发送和接受数据,如同 TCP/IP;这就意味着 WinPcap 不能阻止、过滤或操纵同一机器上的其他应用程序的通讯:它仅仅能简单地“监视”在网络上传输的数据包。所以,它不能提供类似网络流量控制、服务质量调度和个人防火墙之类的支持,因而不能实现服务质量的控制。实验三:协议分析&流量统计程序的编写系统环境开发环境Windows 10 Pro 21H1CLion 2021.1; CMake 3.19; tdm-gcc 9.3; NpCap SDK 1.07一、实验目的理解协议在通信中的作用,掌握常见 IP 协议;掌握基于 NpCap 的抓包软件的开发;掌握协议解析和流量统计的编程方法;二、实验内容利用 NpCap 编写协议分析工具;输出抓取的包和协议分析结构,并统计 IP 的流量(即包的数量)。功能要求:利用 NpCap 捕获数据包,并可根据要求进行数据包过滤。根据 IP 协议,解析每个数据包的 PCI,展示其在不同网络层次所使用的协议结构和具体信息。根据 IP 地址,统计源自该 IP 地址的流量,即捕获到的数据包的数量。运行程序后将捕获的信息输出到标准输出流中。三、实验原理实验的设计依据的原理,包括协议的概念和 NpCap 的接口使用逻辑。3.1 协议说明下面的内容包含了本次实验所涉及到的协议类型的说明。3.1.1 协议栈分析因为 TCP/IP 协议采用分层的结构,所以网络通信时,要传输的数据在发送端是一个逐层封装的过程;而相应地在接收端则是一个逐层分解的过程;如下图所示:在接收端的逐层分解,就是上述封装的逆过程;3.1.2 以太网协议以太网 II 格式时一种帧格式,应用最为广泛,几乎成为了当前以太网的现行标准;它由 RFC894 定义,如下图所示:3.1.3 IP 协议IP 协议是 Internet 的核心协议,它工作在网络层,提供了不可靠无连接的数据传送服务;协议格式如图所示:3.1.4 ICMP 协议ICMP 的全称是 Internet 控制信息协议 (Internet Control Message Protocol)。它提供了很多 Internet 的信息描述服务:例如能够检测网络的运行状况,通知协议有用的网络状态信息;ICMP 是基于 IP 协议的,ICMP 协议格式如图所示:3.1.5 TCP 协议TCP 协议是基于连接的可靠的协议:它负责发收端的协定,然后保持正确可靠的数据传输服务;它在 IP 协议上运行,而 IP 无连接的协议,所以 TCP 丰富了 IP 协议的功能,使它具有可靠的传输服务;TCP 协议格式如图所示:可以看到 TCP 报文段结构由以下的部分组成:源端口:指定了发送端的端口目的端口:指定了接受端的端口号序号:指明了段在即将传输的段序列中的位置确认号:规定成功收到段的序列号,确认序号包含发送确认的一端所期望收到的下一个序号TCP 偏移量:指定了段头的长度。段头的长度取决与段头选项字段中设置的选项保留:指定了一个保留字段,以备将来使用标志:SYN、ACK、PSH、RST、URG、FIN
SYN: 表示同步ACK: 表示确认PSH: 表示尽快的将数据送往接收进程RST: 表示复位连接URG: 表示紧急指针FIN: 表示发送方完成数据发送窗口:指定关于发送端能传输的下一段的大小的指令校验和:校验和包含 TCP 段头和数据部分,用来校验段头和数据部分的可靠性紧急指针:指明段中包含紧急信息,只有当 U R G 标志置 1 时紧急指针才有效选项:指定了公认的段大小,时间戳,选项字段的末端,以及指定了选项字段的边界选项TCP 连接的建立和释放采用了三步握手法,如下图所示:其过程可以描述如下步骤:主机一发出连接序号为 x(seq=x)主机二应答接受主机一的连接请求,并声明自己的序号为 y(seq=y,ACK=x+1)主机一收到确认后,发送第一个数据 TPDU 并确认主机二的序号(seq=x,ACK=y+1)至此,整个连接建立过程正常结束,数据传输已经正式开始。3.1.6 UDP 协议用户数据报协议 UDP 是在 IP 协议上的传输层协议,它提供了无连接的协议服务;它在 IP 协议基础上提供了端口的功能,因此既可让应用程序之间进行通信了。UDP 协议格式如图 3.7 所示:3.2 协议处理NpCap 按照一定的规则提供了 API,和本次实验相关的逻辑如下:3.2.1 NpCap 处理流程NpCap 的工作周期可以被描述为如下序列:pcap_findalldevs & pcap_findalldevs_ex:获得网络接口设备的列表pcap_open & pcap_dump_open & pcap_open_live:打开设备/打开设备数据包pcap_freealldevs:释放获得的设备列表结构所占用的内存pcap_compile & pcap_setfilter:编译并设置过滤器pcap_loop:根据设定的数量来循环捕获数据包,并调用指定的回调处理数据包packet_handler:传入 loop 的回调函数,用来处理被捕获的数据包pcap_close:关闭 NpCap 句柄(即打开的网络设备)简单地说,使用 NpCap 获得网络接口列表后,我们打开一个设备,并设定循环次数,传入指定类型的回调函数来处理被捕获的数据包,并在程序退出之前关闭设备。3.2.2 回调函数设计因为上述协议栈分析中提到了,接收端分析包的内容就是一个逆封装的过程,所以我们可以采用逐层递归的方法来设计我们的回调函数;基本设计如下:(pkt):用来传入 NpCap 循环的,帧处理函数(ethernet):用来处理以太网协议的部分(ipv4) & (ipv6) & (arp):处理 IPv4、IPv6、ARP 协议的报头(icmp) & (tcp) & (udp):处理 ICMP、TCP、UDP 的报文根据设计需求,在判断上一层的协议类型后,将待处理的报文递归给下一层的处理函数即可。四、实验设计关于代码实现方面的设计:4.1 项目组成项目可以分为 handlers、helpers 和 utils 三个部分组成;utils 包含了可复用的无后效逻辑的实现,尽量避免重复代码片段handlers 包含了传给 NpCap 的回调函数以及递归下降法实现的逆封装函数helpers 包含了要实现的额外功能,比如本次实验中的流量统计这三个部分分别使用独立的头文件和源文件组成,被 main 模块引用。4.2 预定义项目所需要的类型定义都包含在 definitions.h 中;包含了根据协议的组成而设计的报文和报头的类型定义;因为最后捕获的数据包是指向一片连续内存块的指针,这里的定义必须保证指定的内存块可以完全转化为对应的包类型才行;因此,需要保证顺序和使用的基本数据类型完全和定义符合。4.3 项目结构最后,整个项目的文件结构如下:CMake target: cn_exp
(root)
├ module
│ └ (NpCap Library files)
NpCap SDK 库文件
├ include
│ ├ definitions.h
预定义的类型声明
│ ├ handlers.h
递归下降法的包处理回调函数的声明
│ ├ helpers.h
流量统计相关方法的声明
│ └ utils.h
可复用模块的函数声明
├ src
│ ├ utils.cpp
可复用模块的函数实现
│ ├ helpers.cpp
流量统计相关方法的实现
│ └ handlers.cpp
递归下降法的包处理回调函数的实现
├ CMakeList.txt
CMake 项目定义文件
└ main.cpp
主进程文件
使用 CMake 加载项目,并构建运行 cn_exp 即可生成目标。五、实现代码GitHub 链接:https://github.com/ma-hunter/cn_exp六、实验结果完成实现上文所述的程序后,运行程序,可以得到下面的结果:6.1 运行结果因为上传截图非常的麻烦,这里仅粘贴标准输出的文本。6.1.1 选择网络设备Hello, World! Hello NpCap!
1.\Device\NPF_{5C8B26D4-9439-4304-B8FB-48A81CB33CF9}WAN Miniport (Network Monitor)
2.\Device\NPF_{C21F9683-BA8A-4AFE-827A-166030BB1466}WAN Miniport (IPv6)
3.\Device\NPF_{1C99E263-4855-4786-97ED-ECAC30A11761}WAN Miniport (IP)
4.\Device\NPF_{1A386F2B-3A3E-49A7-B899-2629C46C4FB3}Hyper-V Virtual Ethernet Adapter #2
5.\Device\NPF_{A30B9DA2-E755-4DF6-8BD4-010B6590B072}Hyper-V Virtual Ethernet Adapter
6.\Device\NPF_{21EAB23F-F3E5-48E0-B370-35B69F40B833}Bluetooth Device (Personal Area Network) #3
7.\Device\NPF_{5CCBE082-6FB3-4754-B27A-3659F98979BE}Realtek RTL8188EU Wireless LAN 802.11n USB 2.0 Network Adapter
8.\Device\NPF_{E919BE86-5601-4998-B187-2C629DE1F9B9}Microsoft Wi-Fi Direct Virtual Adapter #2
9.\Device\NPF_{FF7337C5-5DA3-4AF4-8C55-5A066C578D65}Microsoft Wi-Fi Direct Virtual Adapter
10.\Device\NPF_{43524049-AA60-4F6E-A89E-8AE5BA1EAA93}Realtek PCIe GbE Family Controller
11.\Device\NPF_LoopbackAdapter for loopback traffic capture
Enter the interface number (1-11):
6.1.2 设置监听循环的次数Enter the interface number (1-11):10
listening on Realtek PCIe GbE Family Controller....
Please input the num of packets you want to catch(0 for keeping catching):
6.1.3 TCP 协议解析示例Time: 12:54:00, 129446
Length: 60
Type: 0x800 (IPv4)
Destination address: c:c:b:6:c:e
Source address: 8:a:0:c:6:c
Version: 5
Header length: 5 (20B)
Type of service: 96
Total length: 40
Identification: 22603
Flags: 0
Fragment offset: 64 (512 B)
Protocol: TCP
Checksum: 32469
Source IP address: 39.96.132.69
Destination IP address: 192.168.3.2
Source port: 443
Destination port: 55308
Sequence: 744910189
Acknowledgement: 846425137
Data offset: 0 (0 B)
Flags: ACK
Window: 28927
Checksum: 54318
Urgent pointer: 0
6.1.4 UDP 协议解析示例Time: 12:54:00, 148551
Length: 106
Type: 0x800 (IPv4)
Destination address: 8:a:0:c:6:c
Source address: c:c:b:6:c:e
Version: 5
Header length: 5 (20B)
Type of service: 0
Total length: 92
Identification: 21792
Flags: 0
Fragment offset: 0 (0 B)
Protocol: UDP
Checksum: 0
Source IP address: 192.168.3.2
Destination IP address: 112.32.50.208
Source port: 7726
Destination port: 28078
Length: 72
Checksum: 26356
6.1.5 流量统计示例Flow counts:
IP
Flow
111.206.210.75
3
112.32.50.208
2
13.107.136.9
53
192.168.3.2
34
39.96.132.69
8
6.2 构建记录"D:\Program Files\JetBrains\Toolbox\apps\CLion\ch-0\211.6693.114\bin\cmake\win\bin\cmake.exe" -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - MinGW Makefiles" D:\Workspaces\CLion\cn_exp
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Workspaces/CLion/cn_exp/cmake-build-debug
"D:\Program Files\JetBrains\Toolbox\apps\CLion\ch-0\211.6693.114\bin\cmake\win\bin\cmake.exe" --build D:\Workspaces\CLion\cn_exp\cmake-build-debug --target cn_exp -- -j 4
Scanning dependencies of target cn_exp
[ 20%] Building CXX object CMakeFiles/cn_exp.dir/src/handlers.cpp.obj
[ 40%] Linking CXX executable cn_exp.exe
[100%] Built target cn_exp
构建已完成
七、思考题应用 WINPCAP 能实现哪些网络应用?捕获原始数据包。不管这个包是发往本地机,还是其他机器之间的交换包在数据包被发送到应用程序之前,通过用户定义的规则过滤向网络发送原始数据包对网络通信量做出统计
【推荐阅读】一文看懂linux内核详解linux内核内存管理-写时复制深入了解使用linux查看磁盘io使用情况一. 实验目的1、 加深理解TCP报文结构2、 通过跟踪TCP应用通信,能结合报文对整个通信过程进行分析。3、 理解与掌握TCP协议、UDP协议通信机制4、 熟悉UDP协议报文结构、领会UDP协议通信机制5、 对比TCP、UDP协议主要特点二. 实验环境1、 头歌基于Linux的虚拟机桌面系统2、 网络报文分析工具wireshark三. 相关原理或知识点TCP 首部格式(注:SYN、ACK、RST、FIN、PSH、URG为标记字段(各占1位存储空间)源端口( 16 位):通信发送方使用的端口号目标端口( 16 位):通信接收方使用的端口号序列号( 32 位):用来确保数据可靠传输的唯一值确认号( 32 位):接收方在响应时发送的数值数据偏移( 4 位):标志数据包开始的位置,TCP 头部的长度SYN:(同步)发起连接的数据包:同步 SYN=1 表示这是一个连接请求或连接接受报文。ACK:(确认)确认收到的数据包:只有当 ACK=1 时,确认号字段才有效;当 ACK=0 时,确认号无效。RST:(重置)之前尝试的连接被关闭,(信号差,信号拥挤):当 RST=1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。FIN:(结束)连接成功,传输完毕之后,连接正在断开:用来释放一个连接,FIN=1 表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。PSH:(推送)数据包直接发送给应用,而不是缓存起来:接收 TCP 收到 PSH=1 的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付。URG:(紧急)数据包中承载的内容应该立即由 TCP 协议栈立即进行处理:当 URG=1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。窗口大小( 16 位):匹配缓存区的大小校验和( 16 位):确认 TCP 数据段中的内容是否发送了变化紧急指针( 16 位):明确显示数据之前的 16 进制序列号TCP连接建立过程TCP连接建立过程,双方会产生三个报文,俗称三次握手。①第一次握手:客户端将标志位 SYN 置为 1 ,随机产生一个值SEQ = X,并将该数据包发送给服务器,等待服务器确认;②第二次握手:服务器收到数据包后由标志位SYN = 1,知道客户端请求建立连接,服务器将标志位 SYN 和 ACK 都置为 1 ,ACK = X + 1,随机产生一个值SEQ = Y,并将该数据包发送给客户端以确认连接请求;③第三次握手:客户端收到确认后,检查 ACK 是否为X + 1,ACK 是否为 1 ,如果正确则将标志位 ACK 置为 1 ,ACK = Y + 1,并将该数据包发送给服务器,服务器检查 ACK 是否为1 ,如果正确则连接建立成功。(注:图中Seq代表tcp报文的序号,ack代表tcp报文的确认号。当ACK为1时,ack值有效。)TCP连接关闭过程TCP连接关闭过程,双方通常会产生四个报文,俗称四次握手。有时TCP连接关闭时,只能得到三个报文,这是因为第二次、第三次握手合并到一个报文里了。① 第一次挥手:主动关闭方发送一个 FIN ,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发送数据了(当然,在 FIN 包之前发送出去的数据,如果没有收到对应的 ACK 确认报文,主动关闭方依然会重发这些数据),但此时主动关闭方还可以接受数据。②第二次挥手:被动关闭方收到 FIN 包后,发送一个 ACK 给对方,确认序号为:收到报文序号Seq +收到报文所携带数据长度len+ 1 。上一个报文可能“捎带”了主动关闭方发送的最后一块数据,其长度用字段len来表示。② 第三次挥手:被动关闭方发送一个 FIN ,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发送数据了。④第四次挥手:主动关闭方收到 FIN 后,发送一个 ACK 给被动关闭方,确认序号为:收到报文的序号Seq + 收到报文所携带数据长度len+ 1 ,至此,完成四次挥手。注:上图纵向表示时间轴,第二、三次握手报文的发送方都是被动方,中间间隔的时间内,被动方可以照常向另一方发送数据,直到发送完所有的数据。UDP的首部格式UDP 首部有 8 个字节,由 4 个字段构成,每个字段都是两个字节:源端口: 源端口号,需要对方回信时选用,不需要时全部置 0 ;目的端口:目的端口号,在终点交付报文的时候需要用到;长度:UDP 的数据报的长度(包括首部和数据)其最小值为 8(只有首部)。字段记录了该 UDP 数据包的总长度(以字节为单位),包括 8 字节的 UDP 头和其后的数据部分。最小值是 8(报文头的长度),最大值为 65535 字节;校验和:检测 UDP 数据报在传输中是否有错,有错则丢弃。它的值是通过计算 UDP 数据报及一个伪包头而得到的。校验和的计算方法与通用的一样,都是累加求和。注:端口是用来指明数据的来源(应用程序)以及数据发往的目的地(同样是应用程序)。字段包含了 16 比特的 UDP 协议端口号,它使得多个应用程序可以多路复用同一个传输层协议及 UDP 协议,仅通过端口号来区分不同的应用程序。四.实验任务1、结合具体的报文数据,分析三次握手的过程。2、结合具体的报文数据,分析四次握手的过程。3、结合具体的报文数据,分析各字段的含义。4、完成相关数据的计算统计。5、在实验报告内,计算双方通信所用的时间、计算A方发送的所有的帧的长度之和、计算A->B连接的通信吞吐率是多少。【文章福利】小编推荐自己的Linux内核技术交流群:【977878001】整理一些个人觉得比较好得学习书籍、视频资料;进群私聊群管理领取内核资料包(含视频教程、电子书、实战项目及代码)内核资料直通车:Linux内核源码技术学习路线+视频教程代码资料学习直通车:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈五.TCP协议分析1、TCP连接建立过程分析 图:tcp建立连接三次“握手”包 图:第一次握手第一次握手:客户端将标志位 SYN 置为 1 ,随机产生一个值SEQ = X = 0,并将该数据包发送给服务器,等待服务器确认;图:第二次握手第二次握手:服务器收到数据包后由标志位SYN = 1,直到客户端请求建立连接,服务器将标志位 SYN 和 ACK 都置为 1 ,ACK = X + 1 = 1,随机产生一个值SEQ = Y = 0,并将该数据包发送给客户端以确认连接请求;图:第三次握手第三次握手:客户端收到确认后,检查 ACK 是否为X + 1= 1,如果正确则将标志位 ACK 置为 1 ,SEQ = 1,ACK = Y + 1 = 1,并将该数据包发送给服务器,服务器检查 ACK 是否为1 ,如果正确则连接建立成功,后续开始传输数据。2、TCP关闭连接过程分析 图:tcp关闭连接四次“挥手”包 图:第一次挥手第一次挥手:主动关闭方发送一个 FIN = 1 ,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发送数据了;图:第二次挥手第二次挥手:被动关闭方收到 FIN = 1包后,发送一个 ACK = 1 给对方,确认序号为:收到报文序号Seq +收到报文所携带数据长度len+ 1=1 。上一个报文可能“捎带”了主动关闭方发送的最后一块数据,其长度用字段len来表示。图:第三次挥手第三次挥手:被动关闭方发送一个 FIN = 1 ,同时ACK=1,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发送数据了;图:第四次挥手第四次挥手:主动关闭方收到 FIN 后,发送一个 ACK 给被动关闭方,确认序号为:收到报文的序号Seq + 收到报文所携带数据长度len+ 1 ,至此,完成四次挥手,双向连接关闭。3、6号报文分析图:6号报文摘要
图:6号报文TCP展开展示6号报文分析:Source Port: 2000 //请求端端口:2000Destination Port: 21098 //服务器端端口:21098[Stream index: 0] //tcp流序号:0(wireshark中对源于同一tcp流的包的标记)[TCP Segment Len: 0] //tcp报文长度:0Sequence Number: 1(relative sequence number) //报文序列号:1(相对序号)Sequence Number (raw): 1959254470 //报文序列号:1959254470(绝对序号)[Next Sequence Number: 1(relative sequence number)] //下一序列号:1Acknowledgment Number: 1717(relative ack number) //确认号:1717(相对序号)Acknowledgment number (raw): 1749145722 //确认号:1749145722(绝对序号)0101 … = Header Length: 20 bytes (5) //报文头部长度(数据偏移):20bytesFlags : 0x010 (ACK) //报文类型:ACK000… = Reserved: Not set //保留字段…0… = Nonce: Not set//随机数:无效(随机数(Nonce)是任意的或非重复的值,它包括在经过一个协议的数据交换中,通常为保证活跃度以及避免受重复攻击)…0… = Congestion window Reduced (CWR): Not set//拥塞窗口减少戳:无标记(TCP拥塞控制)…0… =ECN-Echo: Not set //显式拥塞戳:无效(ECN-Echo与TCP拥塞控制)…0… = Urgent: Not set //紧急指针戳:无效…1… = Acknowledgment: Set //确认号戳:有效…0… = Push: Not set //推送戳:无效…0… = Reset: Not set //复位戳:无效…0. = Syn: Not set //同步戳:无效…0 = Fin: Not set //结束戳:无效[TCP Flags …… A……]window: 256 //窗口大小:256(TCP接收者缓冲的字节大小)[ Calculated window size: 65536] //计算出的窗口大小(窗口大小单位*窗口大小)[window size scaling factor: 256] //窗口大小换算系数Checksum: Oxd6a1 [unverified] //校验和[Checksum Status : Unverified] //校验状态Urgent Pointer: 0(如果设置了URG位,这个域将被检查作为额外的指令,告诉CPU从数据包的哪里开始读取数据)[SEQ/ACK analysis]//序列号及确认号的分析结果,当且仅当数据中含有ACK时,才有此项![This is an ACK to the segment in frame: 5]//这是对5号报文的回应[ The RTT to ACK the segment was: 0.00050900e seconds]//往返时延[iRTT: 8.000343000 seconds]//互联网往返时延[Timestamps]//时间戳[Time since first frame in this TCP stream: 0.012839000 seconds]// 从此TCP流中的第一帧开始的时间:0.012839000秒[ Time since previous frame in this TCP stream: 0.000509000 seconds]// 从此TCP流中的上一帧开始的时间:0.000509000秒4、A方(172.16.75.57)TCP报文序列号分析(1) A方第1个报文的序列号(相对值)是多少?图:A方第1个报文A方第1个报文的序列号(相对值)是0(2) A方第2个报文的序列号为什么是1?因为在TCP建立连接的第二次握手中的确认号为ack=X+1=1,A方第2个报文作为TCP建立连接的第三次握手,其序列号seq=X+1=1。图:TCP建立连接的第二次握手中的确认号 图:A方第2个报文(TCP建立连接的第三次握手)(3) 任取2个A方连续发送的报文(非连接建立或关闭期),分析前一个报文的序列号、所携带数据长度跟下一个报文序列号的关系。图:7号报文
图:8号报文有图分析可列表:报文(Frame)序列号(Sequence Number)所携带数据长度TCP Segment)下一个报文序列号(Next Sequence Number)7171723619538195314603413由表可分析得:下一个报文序列号 = 其前一报文序列号 + 其前一报文所携带数据长度(Next Sequence Number = the Front Sequence Number +the Front TCP Segment)(4) A方最后一个报文的序号取值,没有遵循分析中第3条的变化规律,原因何在?图:23号报文
图:26号报文原因分析:在最后的TCP连接关闭时(第四次挥手),主动关闭方收到 FIN 后,会额外发送一个 ACK 给被动关闭方(这就是该26号报文的产生原因),此时26号报文(A方最后一个报文的序号)+1即10568+1得到最终的报文序列号为10569,这就是seq没有遵循分析中第3条的变化规律的原因。(5) 计算A方所传输文件的长度(单位是字节)图:追踪TCP流保存文件 图:大小验证 10567字节五、计算计算双方通信所用的时间、计算A方发送的所有的帧的长度之和、计算A->B连接的通信吞吐率。1、 于最后一个报文的Timestamps里查看通信所用总时间的记录,如图:图:26号报文时间戳双方通信所用的时间:0.085306s2、 A方发送的所有的帧的长度之和为过滤后lengh的数值总和A方发送的所有的帧的长度之和:11497字节3、A->B连接的通信吞吐率:A方发送的所有的帧的长度之和*8/10^6)Mb/双方通信所用的时间s所以:A->B连接的通信吞吐率:1.078Mbps六.UDP协议分析1、UDP报文分析图:UDP报文摘要图:UDP报文分析UDP报文分析:User Datagram Protocol, Src Port: 41831,Dst Port: 8080//UDP协议Source Port: 41831 //请求方端口:41831Destination Port: 8080 //服务器端口:8080Length: 20 //长度:20Checksum: 0x46c2 [unverified] //校验和[checksum Status: Unverified] //校验状态[Stream index: 0] //流序号:02、分析TCP、UDP协议主要特点填写下表:序号特性TCP协议的特点UDP协议的特点1连接面向连接面向无连接2可靠性高可靠较可靠3实时性一般较好4网络开销较大较小5数据负载边界面向字节流,以整个待传输的数据为边界,保证数据正确性基于数据报,以每段报文为边界,不保证传输的数据顺序七.实验总结本次实验作为计算机网络这门课程中很重要的一环:对TCP及UDP协议的理解、学习和调用协议的过程。是极其有必要升入理解和掌握的,通过此次实验,我认识到传输层的TCP/UDP协议与网络层的IP协议是Internet最基本的协议,是Internet国际互联网络的基础。通过在wireshark中对数据报的构造和解析、跟踪TCP应用通信,我加深了对TCP报文结构的理解,并能领会TCP协议通信机制:三次握手以及四次挥手的建立连接/关闭连接的机制,结合报文对整个通信过程进行分析,包括建立连接、传输数据、关闭连接三个重要阶段的主要判别特征以及其作用。而通过对TCP/UDP报文的各个字段的分析,我进一步加深了他们在通信中通过自身标志位从而对每次传输的调节与控制以及整个通信的流量控制和服务质量。我认识到:IP层并不保证数据报一定被正确地递交到接收方,也不指示数据报的发送速度有多快。是由TCP负责快速地发送数据报,以便使用网络容量,同时不会引起网络拥塞:在TCP超时后,要重传没有递交的数据报(即使被正确递交的数据报,也可能存在错序的问题),TCP把接收到的数据报重新装配成正确的顺序。从而达到可靠的通信服务。而UDP在牺牲了部分通信质量的情况下,获得了相比于TCP更快、更高效的数据传输,所以经常被用以传输文件进程中。原文作者:首页 - 内核技术中文网 - 构建全国最权威的内核技术交流分享论坛原文链接:linux网络实验四--TCP/UDP协议分析 - 圈点 - 内核技术中文网 - 构建全国最权威的内核技术交流分享论坛(版权归原文作者所有,侵权留言联系删除)

我要回帖

更多关于 TCP报文格式 的文章