[国嵌攻略][066][ARP协议实现]

以太网通讯

在计算机网络中,数据发送的过程就是把数据按照各层协议层层封装的过程。在这个过程中,最终要使用的协议通常是以太网协议(数据链路层协议)。

 

以太网包格式

目的MAC地址:接收者的物理地址(6字节)

源MAC地址:发送者的物理地址(6字节)

类型:高层数据使用的协议类型(2字节)

数据:高层的数据(46~1500字节)

CRC:校验码(4字节)

 

ARP功能

在以太网络中,每一台计算机的唯一身份表示是MAC地址(物理层的地址),两台计算机要进行通讯,必须要知道对方的MAC地址,但是用户通常只知道对方的IP地址 ,这时就可以利用ARP(地址解析协议)来向局域网中的所有计算机发送ARP请求包,收到请求包并且满足条件的计算机会恢复ARP应答包,告知其MAC地址。所以ARP协议是一种利用IP地址和MAC地址的协议。

 

ARP包格式

ARP包属于网络层,分为请求包和应答包,通过OP字段来区分。

以太网目的地址(6字节)

以太网源地址(6字节)

帧类型(2字节)

硬件类型(2字节)

协议类型(2字节)

硬件地址长度(1字节)

协议地址长度(1字节)

OP(2字节)

发送端以太网地址(6字节)

发送端到IP地址(4字节)

目的以太网地址(6字节)

目的IP地址(4字节)

 

网络字节序

在网络通讯中认为主机都是大端模式。对与多个字节的需要转换,一个字节的不用转换。

小端模式:低地址放低字节,高地址放高字节

大端模式:低地址方高字节,高地址放低字节

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/********************************************************************
*名称:arp.c
*作者:D
*时间:2015.11.26
*功能:ARP协议
*********************************************************************/
 
/********************************************************************
*宏定义
*********************************************************************/
#define ETH_ARP 0x0806   //ARP
#define ETH_RARP 0x0805  //RARP
#define ARP_ETH 0x0001   //ETHERNET
#define ARP_IP 0x0800    //IP
#define ARP_REQ 0x0001   //Request
#define ARP_REP 0x0002   //Reply
 
#define HTONS(n) ( (((n)&0xFF00)>>8) | (((n)&0x00FF)<<8) )   //把unsigned short类型从主机序转换到网络序
 
#define MAC_LENGTH 6       //MAC地址长度
#define IP_LENGTH 4        //IP地址长度
#define PACKET_LENGTH 42   //ARP报文包长度,以太网帧最小长度为64字节,发送时会自动填充为64字节
 
/********************************************************************
*类型定义
*********************************************************************/
//以太网帧首部
typedef struct ehhdr
{
    unsigned char eh_dst[6];   //destination ethernet addrress
    unsigned char eh_src[6];   //source ethernet addresss
    unsigned short eh_type;    //ethernet packet type
}EHHDR, *PEHHDR;
 
//以太网帧数据
typedef struct arphdr
{
    unsigned short arp_hrd;   //format of hardware address
    unsigned short arp_pro;   //format of protocol address
    unsigned char arp_hln;    //length of hardware address
    unsigned char arp_pln;    //length of protocol address
    unsigned short arp_op;    //ARP/RARP operation
 
    unsigned char arp_sha[6];   //sender hardware address
    unsigned char arp_spa[4];   //sender protocol address
    unsigned char arp_tha[6];   //target hardware address
    unsigned char arp_tpa[4];   //target protocol address
}ARPHDR, *PARPHDR;
 
//ARP报文包
typedef struct arpPacket
{
    EHHDR ehhdr;
    ARPHDR arphdr;
}ARPPACKET, *PARPPACKET;
 
/********************************************************************
*全局变量声明
*********************************************************************/
unsigned char eh_src[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};   //MAC发送地址
unsigned char eh_dst[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};   //MAC目的地址
     
unsigned char ip_src[4] = {192, 168, 1, 150};   //IP发送地址
unsigned char ip_dst[4] = {192, 168, 1, 100};   //IP目的地址
 
/********************************************************************
*函数原型声明
*********************************************************************/
void requst_arp();
void create_packet(ARPPACKET *arp_packet);
 
void process_arp(ARPPACKET *arp_packet);
 
/********************************************************************
*名称:requst_arp
*参数:
*   none
*返回:
*   none
*功能:ARP请求
*********************************************************************/
void requst_arp(){
    ARPPACKET arp_packet;   //ARP报文包
 
    //创建ARP报文包
    create_packet(&arp_packet);
     
    //发送ARP报文包
    tx_dm9000(&arp_packet, PACKET_LENGTH);
}
 
/********************************************************************
*名称:create_packet
*参数:
*   arp_packet   报文包
*返回:
*   none
*功能:创建ARP报文包
*********************************************************************/
void create_packet(ARPPACKET *arp_packet){
    //填充以太网帧首部
    memcpy(arp_packet->ehhdr.eh_dst, eh_dst, MAC_LENGTH);   //MAC目的地址
    memcpy(arp_packet->ehhdr.eh_src, eh_src, MAC_LENGTH);   //MAC发送地址
    arp_packet->ehhdr.eh_type = HTONS(ETH_ARP);             //帧类型
     
    //填充以太网帧数据
    arp_packet->arphdr.arp_hrd = HTONS(ARP_ETH);   //硬件类型
    arp_packet->arphdr.arp_pro = HTONS(ARP_IP);    //协议类型
    arp_packet->arphdr.arp_hln = MAC_LENGTH;       //硬件地址长度
    arp_packet->arphdr.arp_pln = IP_LENGTH;        //协议地址长度
    arp_packet->arphdr.arp_op  = HTONS(ARP_REQ);   //操作类型
     
    memcpy(arp_packet->arphdr.arp_sha, eh_src, MAC_LENGTH);   //MAC发送地址
    memcpy(arp_packet->arphdr.arp_spa, ip_src, IP_LENGTH);    //IP发送地址
    memcpy(arp_packet->arphdr.arp_tha, eh_dst, MAC_LENGTH);   //MAC目的地址
    memcpy(arp_packet->arphdr.arp_tpa, ip_dst, IP_LENGTH);    //IP目的地址
}
 
/********************************************************************
*名称:process_arp
*参数:
*   arp_packet   报文包
*返回:
*   none
*功能:处理ARP报文包
*********************************************************************/
void process_arp(ARPPACKET *arp_packet){
    int i;
    unsigned char eh_addr[6];   //物理地址
    unsigned char ip_addr[4];   //协议地址
 
    //提取发送地址
    memcpy(eh_addr, arp_packet->arphdr.arp_sha, MAC_LENGTH);
    memcpy(ip_addr, arp_packet->arphdr.arp_spa, IP_LENGTH);
     
    //打印发送地址
    printf("IP is ");
    for(i = 0; i < IP_LENGTH; i++){
        printf("%3d.", ip_addr[i]);
    }
    printf("\b!");
     
    printf("MAC is ");
    for(i = 0; i < MAC_LENGTH; i++){
        printf("%02X:", eh_addr[i]);
    }
    printf("\b!\n");
}

 

posted @   盛夏夜  阅读(329)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示