• [国嵌攻略][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字节)

    网络字节序

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

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

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

     

    /********************************************************************
    *名称: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("!");
    	
    	printf("MAC is ");
    	for(i = 0; i < MAC_LENGTH; i++){
    		printf("%02X:", eh_addr[i]);
    	}
    	printf("!
    ");
    }
    
  • 相关阅读:
    Combining STDP and binary networks for reinforcement learning from images and sparse rewards
    R-SNN: An Analysis and Design Methodology for Robustifying Spiking Neural Networks against Adversarial Attacks through Noise Filters for Dynamic Vision Sensors
    rust 高阶函数 (high order function)
    Redis从0到精通--三种特殊类型Hyperloglog
    Redis从0到精通--三种特殊类型Geospatial
    Redis从0到精通--三种特殊类型
    Redis从0到精通--Zset
    Redis从0到精通--Set
    Redis从0到精通--Hash
    Redis从0到精通--List
  • 原文地址:https://www.cnblogs.com/d442130165/p/5001134.html
Copyright © 2020-2023  润新知