您的位置:首页 > 其它

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

2015-11-27 16:46 253 查看
以太网通讯

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

以太网包格式

目的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字节)

网络字节序

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

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

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



/********************************************************************
*名称: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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: