[国嵌攻略][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" ); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术