STM32以太網(wǎng)程序解析
本篇博文以上一篇文章《TCP、IP、ARP、ICMP首部分析》為基礎(chǔ),根據(jù)STM32中以太網(wǎng)程序來著重看一下,以太網(wǎng)數(shù)據(jù)包的解析過程。
我們以一個(gè)簡單的服務(wù)器應(yīng)用為主線,進(jìn)行以太網(wǎng)數(shù)據(jù)包的解析。在貼程序之前我們先看一下對于以太網(wǎng)數(shù)據(jù)包各部分的宏定義。
/******************** ETH *********************/
/* 目標(biāo)地址(6),源地址(6),類型/長度(2)*/
#define ETH_HEADER_LEN 14
/* 類型/長度的定義 */
#define ETHTYPE_ARP_H_V 0x08 /* ETH包類型/長度ARP包標(biāo)識(shí)符高位 */
#define ETHTYPE_ARP_L_V 0x06 /* ETH包類型/長度ARP包標(biāo)識(shí)符低位 */
#define ETHTYPE_IP_H_V 0x08 /* ETH包類型/長度IP包標(biāo)識(shí)符高位 */
#define ETHTYPE_IP_L_V 0x00 /* ETH包類型/長度IP包標(biāo)識(shí)符低位 */
/* Ethernet type field (2bytes) */
#define ETH_TYPE_H_P 12 /* ETH包類型/長度偏移地址 */
#define ETH_TYPE_L_P 13 /* ETH包類型/長度偏移地址 */
/* 目的地址與源地址的位置 */
#define ETH_DST_MAC 0 /* ETH包目的MAC偏移地址 */
#define ETH_SRC_MAC 6 /* ETH包源始MAC偏移地址 */
/******************** ARP *********************/
#define ETH_ARP_OPCODE_REPLY_H_V 0x0 /* ARP包操作類型字節(jié):ARP響應(yīng)高位 */
#define ETH_ARP_OPCODE_REPLY_L_V 0x02 /* ARP包操作類型字節(jié):ARP響應(yīng)低位 */
#define ETHTYPE_ARP_L_V 0x06
//#define ETH_ARP_DST_IP_P 0x26 /* arp.dst.ip */
#define ETH_ARP_OPCODE_H_P 0x14 /* ETH包中ARP包類型,ARP頭中存儲(chǔ)操作類型高位的地址 */
#define ETH_ARP_OPCODE_L_P 0x15 /* ETH包中ARP包類型,ARP頭中存儲(chǔ)操作類型低位的地址 */
/* arp.src.mac */
#define ETH_ARP_SRC_MAC_P 0x16 /* ETH包中ARP包類型,ARP頭中存儲(chǔ)源始MAC的首地址 */
#define ETH_ARP_SRC_IP_P 0x1c /* ETH包中ARP包類型,ARP頭中存儲(chǔ)源始IP的首地址 */
#define ETH_ARP_DST_MAC_P 0x20 /* ETH包中ARP包類型,ARP頭中存儲(chǔ)目的MAC的首地址 */
#define ETH_ARP_DST_IP_P 0x26 /* ETH包中ARP包類型,ARP頭中存儲(chǔ)目的IP的首地址 */
/******************** IP *********************/
#define IP_HEADER_LEN 20 /* IP包頭文件長度 */
#define IP_SRC_P 0x1a /* ETH包中IP包類型,IP頭中存儲(chǔ)源始IP地址的首地址 */
#define IP_DST_P 0x1e /* ETH包中IP包類型,IP頭中存儲(chǔ)目的IP地址的首地址 */
#define IP_HEADER_LEN_VER_P 0xe /* ETH包中IP包類型,IP頭中存儲(chǔ)版本的首地址 */
#define IP_CHECKSUM_P 0x18 /* ETH包中IP包類型,IP頭中存儲(chǔ)校驗(yàn)和的首地址 */
#define IP_TTL_P 0x16 /* ETH包中IP包類型,IP頭中存儲(chǔ)生存時(shí)間的首地址 */
#define IP_FLAGS_P 0x14 /* ETH包中IP包類型,IP頭中存儲(chǔ)標(biāo)志的首地址 */
#define IP_P 0xe /* ETH包中IP包類型,IP頭的首地址 */
#define IP_TOTLEN_H_P 0x10 /* ETH包中IP包類型,IP頭中存儲(chǔ)包裹總長高位的地址 */
#define IP_TOTLEN_L_P 0x11 /* ETH包中IP包類型,IP頭中存儲(chǔ)包裹總長低位的地址 */
#define IP_PROTO_P 0x17
#define IP_PROTO_ICMP_V 1 /* ETH包中IP包類型,IP頭中協(xié)議代碼1表示ICMP */
#define IP_PROTO_TCP_V 6 /* ETH包中IP包類型,IP頭中協(xié)議代碼6表示TCP */
#define IP_PROTO_UDP_V 17 /* ETH包中IP包類型,IP頭中協(xié)議代碼17表示UDP */
/******************** ICMP *********************/
#define ICMP_TYPE_ECHOREPLY_V 0 /* ETH包中IP包類型ICMP包,ICMP頭類型代碼回射應(yīng)答 */
#define ICMP_TYPE_ECHOREQUEST_V 8 /* ETH包中IP包類型ICMP包,ICMP頭類型代碼回射請求 */
//
#define ICMP_TYPE_P 0x22 /* ETH包中IP包類型ICMP包,ICMP頭類型代碼的首地址 */
#define ICMP_CHECKSUM_P 0x24 /* ETH包中IP包類型ICMP包,ICMP頭校驗(yàn)和的首地址 */
/******************** UDP *********************/
#define UDP_HEADER_LEN 8 /* ETH包中IP包類型UDP包,UDP頭長度 */
//
#define UDP_SRC_PORT_H_P 0x22 /* ETH包中IP包類型UDP包,UDP頭源始端口號高位地址 */
#define UDP_SRC_PORT_L_P 0x23 /* ETH包中IP包類型UDP包,UDP頭源始端口號低位地址 */
#define UDP_DST_PORT_H_P 0x24 /* ETH包中IP包類型UDP包,UDP頭目的端口號高位地址 */
#define UDP_DST_PORT_L_P 0x25 /* ETH包中IP包類型UDP包,UDP頭目的端口號低位地址 */
//
#define UDP_LEN_H_P 0x26 /* ETH包中IP包類型UDP包,UDP頭UDP長度高位地址 */
#define UDP_LEN_L_P 0x27 /* ETH包中IP包類型UDP包,UDP頭UDP長度低位地址 */
#define UDP_CHECKSUM_H_P 0x28 /* ETH包中IP包類型UDP包,UDP頭UDP校驗(yàn)和高位地址 */
#define UDP_CHECKSUM_L_P 0x29 /* ETH包中IP包類型UDP包,UDP頭UDP校驗(yàn)和低位地址 */
#define UDP_DATA_P 0x2a /* ETH包中IP包類型UDP包,UDP包數(shù)據(jù)區(qū)首地址 */
/******************** TCP *********************/
#define TCP_SRC_PORT_H_P 0x22 /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)源始端口高位的地址 */
#define TCP_SRC_PORT_L_P 0x23 /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)源始端口低位的地址 */
#define TCP_DST_PORT_H_P 0x24 /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)目的端口高位的地址 */
#define TCP_DST_PORT_L_P 0x25 /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)目的端口低位的地址 */
/* the tcp seq number is 4 bytes 0x26-0x29 */
#define TCP_SEQ_H_P 0x26 /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)數(shù)據(jù)序號的首地址 */
#define TCP_SEQACK_H_P 0x2a /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)確認(rèn)序號的首地址 */
#define TCP_FLAGS_P 0x2f /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)標(biāo)志字節(jié)的地址 */
#define TCP_FLAGS_SYN_V 2
#define TCP_FLAGS_FIN_V 1
#define TCP_FLAGS_PUSH_V 8
#define TCP_FLAGS_SYNACK_V 0x12 /* ETH包中IP包類型TCP包,TCP頭中同步比特確認(rèn)值 */
#define TCP_FLAGS_ACK_V 0x10 /* ETH包中IP包類型TCP包,TCP頭中確認(rèn)比特值 */
#define TCP_FLAGS_PSHACK_V 0x18 /* ETH包中IP包類型TCP包,TCP頭中PSH比特確認(rèn)值 */
/* TCP數(shù)據(jù)頭中沒有可選選項(xiàng)字節(jié) */
#define TCP_HEADER_LEN_PLAIN 20 /* ETH包中IP包類型TCP包,TCP頭長度(如果不包含可選選項(xiàng)) */
#define TCP_HEADER_LEN_P 0x2e /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)偏移的首地址 */
#define TCP_CHECKSUM_H_P 0x32 /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)包校驗(yàn)和地址 */
#define TCP_CHECKSUM_L_P 0x33 /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)包校驗(yàn)和地址 */
#define TCP_OPTIONS_P 0x36 /* ETH包中IP包類型TCP包,TCP頭中存儲(chǔ)可選選項(xiàng)的首地址 */
上面的宏定義中記錄了在各個(gè)協(xié)議首部一些關(guān)鍵數(shù)據(jù)的位置及關(guān)鍵代碼的參數(shù)。對于占用多個(gè)字節(jié)的參數(shù)高位在前
在以太網(wǎng)中數(shù)據(jù)包的解析主要有4條線路,分別是
ETH ---> ARP
ETH ---> IP ---> TCP ---> 應(yīng)用程序
ETH ---> IP ---> UDP ---> 應(yīng)用程序
ETH ---> IP ---> ICMP
下面我們來詳細(xì)看一下程序,我們將逐行的進(jìn)行分析。
int simple_server(void)
{
unsigned int plen,dat_p,i1=0,payloadlen=0;
unsigned char i=0,*buf1 = 0;
signed char cmd;
/* 將自己設(shè)定的mac,ip,wwwport賦值給系統(tǒng)變量 */
init_ip_arp_udp_tcp(mymac,myip,mywwwport);
printf("nr神舟III號MAC地址:0x%x,0x%x,0x%x,0x%x,0x%x,0x%x",mymac[0],mymac[1],mymac[2],mymac[3],mymac[4],mymac[5]);
printf("nr IP地址:%d.%d.%d.%d",myip[0],myip[1],myip[2],myip[3]);
printf("nr 端口號:%dnrnr",mywwwport);
while(1)
{
/* 判斷是否有接收到有