STM32以太网程序解析四

发布者:心愿实现最新更新时间:2022-01-18 来源: eefocus关键字:STM32  以太网程序  校验和 手机看文章 扫描二维码
随时随地手机看文章

函数先清空校验和,然后设置IP首部标志总第0x14字节中不分段位为1,表示不允许分段,段偏移量为0,设置生存时间为64跳。最后计算校验和,填充校验和。校验和计算函数的计算方法我们这里不做介绍。


make_ip函数执行完成后,将ICMP相应的包类型修改为回射应答。然后填写IP校验和,最后通过ENC28J60将数据发送出去。


48行处理完ICMP回射应答后,通过continue语句重新接收数据包做处理。


如果不是ICMP包41行if函数不成立,程序继续往下执行。


52行if语句判断是否TCP包,判断的依据为查看IP首部(总第0x17字节)的协议代码是否为6(6代表TCP),并且TCP首部目的端口(总第0x24字节和0x25字节)是否与服务器的port相同,如果不正确则说明不是TCP包,程序继续往下执行。如果两者都正确说明是TCP包,if条件成立,执行if里面的函数


57行if语句判断TCP包类型,判断方法是对TCP首部中的6个标识位进行识别(总第0x2F字节的后6位)判断SYN位是否置位,如果没有置位则if条件不成立继续往下执行,如果SYN位置位说明TCP包是一个连接请求TCP包。


60行对连接请求TCP包做应答,该行函数的内部操作是


1. void make_tcp_synack_from_syn(unsigned char *buf)  


2. {  


3.     unsigned  int ck;  


4.       


5.     // 填写包的目的MAC地址以及源MAC地址    


6.     make_eth(buf);  


7.       


8.     // 计算包长度=IP头(20)+TCP头(24)  


9.     buf[IP_TOTLEN_H_P]=0;  


10.     buf[IP_TOTLEN_L_P]=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+4;  


11.       


12.     // 填写包的目的IP地址以及源IP地址   


13.     make_ip(buf);  


14.   


15.     buf[TCP_FLAGS_P]=TCP_FLAGS_SYNACK_V;  


16.       


17.     // 填写TCP头   


18.     make_tcphead(buf,1,1,0);  


19.       


20.     // 计算校验和 长度=8 (开始于ip.src) + TCP头长(20) + 可选选项(4字节,mss)   


21.     ck=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+4,2);  


22.     buf[TCP_CHECKSUM_H_P]=ck>>8;  


23.     buf[TCP_CHECKSUM_L_P]=ck& 0xff;  


24.       


25.     printf("nr神舟III号[%d.%d.%d.%d]发送SYN包响应",ipaddr[0],ipaddr[1],ipaddr[2],ipaddr[3]);  


26.       


27.     enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+4+ETH_HEADER_LEN,buf);  


28. }  


首先是make_eth,然后计算包裹长度填入IP首部的包裹长度(总第0x10字节和0x11字节),接着make_ip,接着修改TCP首部中6个标志为中的ACK与SYN位置位,表示同步确认。接着调用make_tcphead函数,该函数的内部操作:"首先将TCP首部的源端口与目的端口互相对调,然后设置数据序号与确认序号,接着设置选项字节,最后更新偏移位。"接着计算校验和填充TCP首部中的校验和,最后通过ENC28J60将数据发送出去。


 


61行,发送同步请求应答TCP包后,continue语句重新接收数据包做处理。


65行通过if语句判断TCP包类型,判断方法是对TCP首部中的6个标识位进行识别(总第0x2F字节的后6位)判断ACK位是否置位,如果没有置位则if条件不成立继续往下执行,如果ACK位置位说明TCP包是一个TCP确认包。接下来就解析这个包数据


70行初始化数据格式,并获取TCP包,数据区长度。数据区长度保存在全局变量info_data_len中


71行用于获取数据区首地址在buf中的位置。其结果返回到dat_p变量。


74行判断是否为一个无数据的TCP包,如果有数据则不进入if内部,程序继续往下进行,如果是无数据的TCP包,则在if内部做继续判断


77行在上一个if内部继续做判断通过6个bit的标志位判断是否为要求释放连接(终止)的TCP包。如果不是则,continue继续等待重新接收数据包,如果是执行81行函数


81行函数对要求释放连接(终止)的TCP包做应答,它内部到操作函数是


1. void make_tcp_ack_from_any(unsigned char *buf)  


2. {  


3.     unsigned  int j;  


4.   


5.     // 填写包的目的MAC地址以及源MAC地址    


6.     make_eth(buf);  


7.       


8.     // 填充包的类型为ack响应包   


9.     buf[TCP_FLAGS_P]=TCP_FLAGS_ACK_V;  


10.   


11.     // 判断接收的TCP包内是否有数据   


12.     if (info_data_len==0)  


13.     {  


14.         make_tcphead(buf,1,0,1);   


15.     }  


16.     else  


17.     {  


18.         make_tcphead(buf,info_data_len,0,1);   


19.     }  


20.       


21.     // 设置IP包头中总长度:长度=IP头(20)+TCP头(20(不包括选项字节))   


22.     j=IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN;  


23.     buf[IP_TOTLEN_H_P]=j>>8;  


24.     buf[IP_TOTLEN_L_P]=j& 0xff;  


25.   


26.    // 填写包的目的IP地址以及源IP地址   


27.     make_ip(buf);  


28.   


29.     // 计算校验和 长度=8 (开始于ip.src) + TCP头长(20) + 数据长度   


30.     j=checksum(&buf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN,2);  


31.     buf[TCP_CHECKSUM_H_P]=j>>8;  


32.     buf[TCP_CHECKSUM_L_P]=j& 0xff;  


33.       


34.     printf("nr神舟III号[%d.%d.%d.%d]发送ACK包响应",ipaddr[0],ipaddr[1],ipaddr[2],ipaddr[3]);  


35.       


36.     enc28j60PacketSend(IP_HEADER_LEN+TCP_HEADER_LEN_PLAIN+ETH_HEADER_LEN,buf);  


37. }  


首先make_eth,然后修改TCP中标志位,使TCP包变为应答包,根据TCP包中是否有数据make_tcphead,接着设置IP首部中包裹长度,接着make_ip,接着填充校验和,最后通过ENC28J60函数将数据发送出去。


如果是有数据的TCP包则接下来解析数据。


88行到93行为判断网络为Telnet方式登录的处理程序。首先判断的依据是真正用户数据(TCP数据)的前四个字节不是“GET ”,如果是Telnet登录方式则通过91行的函数填充数据。然后通过92行语句跳转至131行至135行,发送TCP确认包及TCP数据包。


94行到 101行为判断通过网页方式登录的处理程序。首先判断的依据是真正用户数据(TCP数据)的第4个字节和第5个字节为“/ ”,如果是这种方式则通过97行至99行填充TCP要发送的数据。同100行语句跳转至131行至135行,发送TCP确认包及TCP数据包。


如果不是以上两者之一的登录方式,则程序继续往下执行,分析TCP数据


104行分析网页控制命令,函数内部操作为


1. signed char analyse_get_url(char *str)  


2. {  


3.     unsigned char i=0;  


4.       


5.     // 密码错误则返回-1   


6.     if (verify_password(str)==0)  


7.     {  


8.         return(-1);  


9.     }  


10.   


11.     // 密码不要长于9个,寻找第一个'/'   


12.     while(*str && i<10 && *str >',' && *str<'{')  


13.     {  


14.         if (*str=='/')  


15.         {  


16.             str++;  


17.             break;  


18.         }  


19.         i++;  


20.         str++;  


21.     }  


22.   


23.     if (*str < 0x3a && *str > 0x2f)  


24.     {  


25.         // ascii码表中的数字   


26.         return(*str-0x30);  


27.     }  


28.   


29.     return(-2);  


30. }  


该函数的实参是&(buf[dat_p+5]),即从实际用户数据的第5个字节开始分析,首先通过verify_password函数验证密码是否正确,验证的方式是通过strncmp函数将数据与密码做依次对比。接下来通过while语句寻找第一个“/”,然后返回“/”后面的那个数字作为命令。


当cmd命令为负数时实际上是没有通过密码验证的。当cmd为正数时是正确的命令根据不同的命令做不同的操作。具体看106行至124行。


127行用于更新网页信息,整个函数实际上都是在填充TCP数据。这个我也没太研究这里就不说了。。


如果也不是TCP包,我们继续往下执行程序看是否为UDP包


142行if语句判断是否UDP包,判断的依据为查看IP首部(总第0x17字节)的协议代码是否为17(17代表UDP),并且UDP首部目的端口(总第0x24字节和0x25字节)是否为1200.如果不正确则说明不是UDP包,程序继续往下执行。如果是UDP包,则执行if里面的函数


145行至147行用于获取UDP数据长度。


150行至153行,将UDP数据导入到buf1数组中


156行用于回复一个UDP应答包,包的发送的数据内容与接收到的包数据内容相同。

关键字:STM32  以太网程序  校验和 引用地址:STM32以太网程序解析四

上一篇:STM32以太网程序解析二
下一篇:STM32以太网程序解析三

推荐阅读最新更新时间:2024-11-12 10:25

STM32-(01):认识ARM
ARM(Advanced RISC Machines)是微处理器行业的一家知名企业,设计了大量的高性能、廉价、低耗能的RISC(Reduced Instruction Set Computer,中文是精简指令集计算机)处理器、相关技术及软件。技术具有性能高、成本低和能耗省的特点。适用于多种领域,比如嵌入控制、消费/教育类多媒体、DSP和移动式应用等。 市场份额 手机处理器90%以上的市场份额 上网本处理器30%的市场份额 平板电脑处理器70%的市场份额 基于ARM技术的微处理器应用约占据了32位嵌入式微处理器80%以上的市场份额。 风靡全球的几大原因: 1、功耗低 2、功能强 3、32位指令集 4、合作伙伴众多 5、产品线丰富
[单片机]
STM32-(01):认识ARM
stm32 DA 数模转换
stm32并不是所有的型号都有DAC功能,只有stm32f103xC/D/E系列 才有DAC转换功能。由于库函数手册中没有相关说明,所以只能通过在MDK提供的相关库文件 stm32f10x_dac.c 中找到相应的DAC函数,做了一番尝试。 折腾了一天,实现了DAC的转换和三角波的输出。我使用的是 stm32rct6的芯片,有两个DAC通道,在PA4和PA5两个引脚上。 DAC的库函数配置相关参数说明: void DAC_Configuration(void) { DAC_InitTypeDef DAC_InitStructure; DAC_InitStructure.DAC_Trigger = DAC_Tr
[单片机]
STM32-(36):CAN总线(概述)
CAN 是 Controller Area Network 的缩写(以下称为 CAN) ,是ISO国际标准化的串行通信协议。 在当前的汽乍产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统被开发了出来 。由于这些系统之间通信所用的数据类型及对可靠性的要求不尽相同,由多条总线构成的情况很多,线束的数量也随之增加。为适应“减少线束的数量”、“通过多个 LAN 进行大量数据的高速通信”的需要,1986年德国电气商博世公司开发出面向汽车的 CAN 通信协议。此后, CAN 通过 ISO 1898及 ISO 11519进行了标准化,现在在欧洲已是汽车网络的标准协议。 现在, CAN 的高性能和可靠性己被认同,
[单片机]
STM32-(36):CAN总线(概述)
2023年 STM32中国峰会开启全新篇章
今年的STM32中国峰会已经圆满结束,我们诚挚感谢各位的持续支持和关注。下面就让一组关键数据带我们回顾本届峰会的精彩历程! • 2,600多名观众亲临2023 STM32中国峰会现场 • 75,000多名观众在线观看了2023 STM32中国峰会 • 截至5月17日,共收集2,433张直播图片,浏览量高达341,495次 • 围绕边缘AI&信息安全、连接、生态系统&开发者优先计划以及智能工业&高性能MCU/MPU四大主题,共计29场主题演讲和28场研讨会在峰会现场举办 • 现场展示200多款产品, 覆盖边缘AI,网络连接,信息安全,生态系统,开发者优先解决方案和STM32 垂直应用等广泛领域 • 11
[单片机]
2023年 <font color='red'>STM32</font>中国峰会开启全新篇章
STM32电机矢量控制】记录6——FOC运行流程
坐标变换理论: 坐标变换理论可以降低马达方程的复杂性,利用坐标变换把定子及转子变量变换到一个旋转坐标系中,该坐标系的转速为角速度ω。 假设fax, fbx, fcx 为三相瞬时变量,位于相移120度的a,b,c坐标上,fqx, fdx, f0x 为其变换变量,位于正交坐标d,q上: 则,变换方程为: 3个变换方程用于矢量控制: Clarke: ω=0, θ(0)=0 - θ=0; Park: ω=ωr, θ(0)=θr(0) - θ=θr; 反Park: ω=-ωr , θ(0)= θr(0) - θ=-θr 所以有: Clarke将定子电流转变为静止直角参考坐标(称αβ坐标); 然后,Park将电流
[单片机]
【<font color='red'>STM32</font>电机矢量控制】记录6——FOC运行流程
STM32串口空闲中断的使用
今天完善了USART串口接收数据函数以及程序,在每个USART外设上都添加了串口空闲中断函数。其步骤如下: 添加总线空闲中断功能的优点: a) 可以准确地判断出串口数据是否接收完毕,不需要额外添加定时器作数据接收完毕超时检测,不仅可以减少了TIM定时器外设 的使用,提高系统性能,而且可以增强程序的可读性(因为使用TIM定时器做超时检测时,需要在TIM定时器中断函数中添加一个 USART_RX_Over的标识符,影响了程序的可读性); 添加总线空闲中断功能的需要注意的地方: a) 在使用串口空闲中断时需要添加读DR位(数据寄存器)空闲中断变量,因为每次触发串口空闲中断时,需要读取对应USART的DR位(数据寄存器)才能清除
[单片机]
<font color='red'>STM32</font>串口空闲中断的使用
STM32-IIC 配置解说
STM32-IIC 配置解说(原创)STM32 - I2C 简介 :I2C 总线接口连接微控制器和串行 I2C 总线。它提供多主机功能,控制所有 I2C总线特定的时序、协议、仲裁和定时。支持标准和快速两种模式,另外 STM32的 I2C 可以使用 DMA 方式操作。本文主要以一个实例来介绍 STM32-I2C 的配置方式和具体在工程中通过调用哪些库函数来实现 I2C 器件的 通信 。实例:写入数据到器件 AT24C02 并将存入的数据读出好,我们先来讲讲 STM32 I2C 模块的端口基本配置,由 STM32 中文参考手册可以查到在使用 I2C 时对应的引脚要配置成哪种模式。 SCL 和 SDA 引脚都配置成开漏复用输出 本人用的
[单片机]
STM32的USART使用DMA--操作
使用STM32的DMA来处理USART3的RX的多数据 注意:DMA的中断产生条件中,TC=transfer complete interrupt产生,需要DMA的buffer满才会产生。 只有当DMA内存中的数据个数达到20个时候才能产生中断。定义如下。DMA_InitStructure.DMA_BufferSize = 20;//sizeof(Ch3DMABuffer); static usart3_dma_config(void) { DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHBPeriphClo
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved