阅读:3162回复:4
已经知道对方IP,如何通过IP得到他的Mac地址呢
想在底层构建Packet发出去,但只知道他的IP,以太帧头不知到怎么填!
|
|
沙发#
发布于:2004-04-26 10:20
在局域网或广域网上把报文从一台机器发送到另一台机器,如果不知道目的机器的物理地址就会发生问题。需要一些方法能把I P地址(应用提供)解析为和网络相连的机器的硬件物理地址。
一种强制的方法是在每台机器上建一个用于把I P地址转化成物理地址的解析表。于是,当一个应用程序要把数据发送到另一台机器时,软件就检查这个转换表以得到物理地址。这个方法存在一些问题,这些问题也就是几乎没有这样实现的原因。最致命的缺点是一旦发生 一些变化,每台机器上的地址表就要更新。 为了解决这个问题,开发了地址解析协议( A R P )。A R P的任务是把I P地址转化成物理地址,这样做,就消除了应用程序需要知道物理地址的必要性。用最简单的术语表述, A R P就是把I P地址转换成相应物理地址的转换表。这个表称为A R P表。A R P表的排列如图5 - 4所示。A R P在存储器中维护一个c a c h e,这个c a c h e称为ARP cache,通常搜索ARP cache进行匹配,假如 没有匹配成功就检查A R P表。 I F索引 物理地址 I P地址 类型 表项1 表项2 表项3 表项n ARP cache中的每一行对应一个设备,每一个设备存储以下信息: • IF索引―物理端口(接口)。 • 物理地址―设备的物理地址。 • IP地址―和物理地址对应的I P地址。 • 类型―这一行对应的表项类型。 类型有4种可能的值,值2意味着表项是无效的,值3意味着映射是动态的(表项可能改变),值4说明是静态项(表项不变化),值1意味着不是上面的任何一种情况。当A R P解析一个I P地址时,它会搜索ARP cache和A R P表作匹配。如果找到了, A R P就把物理地址返回给提供I P地址的应用,假如A R P没找到一个匹配的I P地址,它就会向网络上发布消息,这个称为A R P请求的消息,被广播到局域网上的每一个设备。A R P请求包括接收设备的I P地址。假如一个设备认出此I P地址属于自己,就把包含自己物理地址的应答报文返回给产生A R P请求的机器, A R P请求机器会把此信息放到A R P表和A R P c a c h e中以备将来之用。使用这种方式, A R P能决定任何I P地址对应机器的物理地址。A R P请求和A R P应答报文的格式如图5 - 5所示,当一个A R P请求发出时,除了接收端硬件地址(正是请求机想知道的)之外所有域都被使用。A R P应答中,使用所有的域。 图5-5 ARP请求和应答报文格式 硬件类型( 1 6位) 协议类型( 1 6位) 硬件地址长度协议地址长度 操作码( 1 6位) 发送硬件地址 发送I P地址 接收端硬件地址 接收端I P地址 1. 硬件类型 硬件类型识别硬件接口类型,合法的值是: 类型描述 1 以太网 2 实验以太网 3 X . 2 5 4 Proteon ProNET(令牌环) 5 混沌网( c h a o s ) 6 IEEE 802.X 7 A R C网络 2. 协议类型 硬件类型( 1 6位) 协议类型( 1 6位) 发送I P地址 接收端I P地址 接收端硬件地址 发送硬件地址 操作码( 1 6位) 硬件地址长度协议地址长度 协议类型标识发送设备所使用的协议类型, T C P / I P中,这些协议通常是E t h e r Ty p e,合法的值是: 十进制 描述 5 1 2 XEROX PUP 5 1 3 P U P地址翻译 1 5 3 6 XEROXNS IDP 2 0 4 8 网际协议 2 0 4 9 X . 2 5 2 0 5 0 N B S 2 0 5 1 E C M A 2 0 5 2 混沌网络 2 0 5 3 X . 2 5第三层 2 0 5 4 地址解析协议( A R P ) 2 0 5 5 X E R O X网络系统 4 0 9 6 伯克利Tr a i l e r 2 1 0 0 0 BBN Simnet 2 4 5 7 7 DEC MOP (维护操作协议) D u m p / L o a d 2 4 5 7 8 DEC MOP (维护操作协议)远程控制 2 4 5 7 9 DEC DECnet Phase 5 2 4 5 8 0 DEC LAT 2 4 5 8 2 D E C 2 4 5 8 3 D E C 3 2 7 7 3 HP Probe协议 3 2 7 8 4 E x c e l a n 3 2 8 2 1 反向地址解析协议( R A R P ) 3 2 8 2 3 A p p l e Ta l k 3 2 8 2 4 DEC 局部网桥协议 如果协议不是E t h e r Ty p e,允许使用其他值。 3. 硬件地址长度 数据报中硬件地址以字节为单位的长度。 4. 协议地址长度 数据报中所用协议地址以字节为单位的长度。 5. 操作码 操作码(O p c o d e)指明数据报是A R P请求还是A R P应答,假如是A R P请求,此值为1;假 如数据报是A R P应答,此值为2。 6. 发送方硬件地址 发送方设备的硬件地址。 7. 发送方I P地址 发送方设备的I P地址。 8. 接收方硬件地址 接收方设备的硬件地址。 9. 接收方I P地址 接收方设备的I P地址。 |
|
板凳#
发布于:2004-04-26 12:46
贴个代码给你,我自己写的,可以用的。
void SV_arpRequest_KE(UINT uSourceIP, UINT uDestinationIP, PUCHAR pSrcMACAddress, PADAPT pAdapt) { NDIS_STATUS Status; PNDIS_PACKET ArpPacket = NULL; PNDIS_BUFFER pArpPacketMacHeaderBuffer = NULL; PSEND_RSVD pSendRsvd = NULL; PMACHEADER pMacHeaderContent = NULL; PEtherARP pEtherArpContent = NULL; UINT BufferLen; NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress; HighestAcceptableAddress.LowPart = -1; HighestAcceptableAddress.HighPart = -1; DbgPrint(\"---In ARP Request----\"); Status = NdisAllocateMemory(&pMacHeaderContent,BUFFER_SIZE,0,HighestAcceptableAddress); if( (Status == NDIS_STATUS_SUCCESS) && (pMacHeaderContent != NULL) ) { NdisZeroMemory(pMacHeaderContent,BUFFER_SIZE); pEtherArpContent = (PEtherARP)( (PUCHAR)pMacHeaderContent + sizeof(MACHEADER) ); //填充MAC首部 RtlCopyMemory(pMacHeaderContent->chDestinateMAC,BroadcastAddress,BYTE_OF_MACADDRESS); RtlCopyMemory(pMacHeaderContent->chSourceMAC,pSrcMACAddress,BYTE_OF_MACADDRESS); pMacHeaderContent->nEtherType = htons(ETHERTYPE_ARP); //填充ARP首部 pEtherArpContent->arpHeader.arp_hrdType = htons(ARPHEAD_ETHER); //表示是以太网 pEtherArpContent->arpHeader.arp_proType = htons(ETHERTYPE_IP); //IP pEtherArpContent->arpHeader.arp_hrdLength = sizeof(pEtherArpContent->arp_senderHrdAddress); pEtherArpContent->arpHeader.arp_proLength = sizeof(pEtherArpContent->arp_senderProAddress); pEtherArpContent->arpHeader.arp_op = htons(ARPOP_REQUEST); DbgPrint(\"SourceIP is %u\\nDest IPis %u\",uSourceIP,uDestinationIP); //填充ARP帧内容 RtlCopyMemory(pEtherArpContent->arp_senderHrdAddress,pSrcMACAddress,BYTE_OF_MACADDRESS); RtlCopyMemory(pEtherArpContent->arp_senderProAddress,&uSourceIP,BYTE_OF_IPADDRESS); RtlCopyMemory(pEtherArpContent->arp_targetProAddress,&uDestinationIP,BYTE_OF_IPADDRESS); DbgPrint(\"-------After assigned:\\nSourceIP is %u\\nDest IPis %u--------\", pEtherArpContent->arp_senderProAddress,pEtherArpContent->arp_targetProAddress); NdisDprAllocatePacket(&Status, &ArpPacket, pAdapt->SendPacketPoolHandle); if(Status != NDIS_STATUS_SUCCESS) { DbgPrint(\"分配包失败!(Allocate Packet Failure!)\"); return; } NdisAllocateBuffer(&Status, &pArpPacketMacHeaderBuffer, pAdapt->SendPacketPoolHandle, (PVOID)pMacHeaderContent, sizeof(MACHEADER)+sizeof(EtherARP)); if(Status != NDIS_STATUS_SUCCESS) { DbgPrint(\"分配BUFFER失败!(Allocate Buffer Failure!)\"); return; } pSendRsvd = (PSEND_RSVD)(ArpPacket->ProtocolReserved); pSendRsvd->OriginalPkt = NULL; ArpPacket->Private.Head = NULL; ArpPacket->Private.Tail = NULL; NdisChainBufferAtFront(ArpPacket,pArpPacketMacHeaderBuffer); NdisSend(&Status,pAdapt->BindingHandle,ArpPacket); // // 释放资源: 没有Pending,则此处释放,如果Pending,则在SendComplete释放! // if (Status == NDIS_STATUS_PENDING){ DbgPrint(\" ARP Send Pending!\\n\"); } else { DbgPrint(\"ARP Send OK!\\n\"); NdisUnchainBufferAtFront(ArpPacket,&pArpPacketMacHeaderBuffer); NdisQueryBufferSafe(pArpPacketMacHeaderBuffer,(PVOID *)&pMacHeaderContent,&BufferLen,32); NdisFreeBuffer(pArpPacketMacHeaderBuffer); NdisFreeMemory(pMacHeaderContent,BUFFER_SIZE,0); NdisFreePacket(ArpPacket); } } else { //分配内存失败 DbgPrint(\"分配内存失败(Allocate Memory Failure!)\"); return; } } |
|
地板#
发布于:2004-04-26 12:47
这个是上面代码用到的结构和宏定义
#define ETHERTYPE_ARP 0x0806 #define ETHERTYPE_IP 0x0800 #define ARPHEAD_ETHER 1 #define ARPOP_REQUEST 1 #define ARPOP_REPLY 2 const UCHAR BroadcastAddress[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//发ARP包用的广播地址 typedef struct _tagARPHEADER { USHORT arp_hrdType; //format of hardware address USHORT arp_proType; //format of protocol address UCHAR arp_hrdLength; //hardware address length UCHAR arp_proLength; //protocol address length USHORT arp_op; //ARP operation code }ARPHeader,*PARPHeader; typedef struct _tagETHER_ARP { ARPHeader arpHeader; // fixed-size header UCHAR arp_senderHrdAddress[6]; // sender hardware address UCHAR arp_senderProAddress[4]; // sender protocol address UCHAR arp_targetHrdAddress[6]; // target hardware address UCHAR arp_targetProAddress[4]; // target protocol address }EtherARP,*PEtherARP; typedef struct _tagHrdAddress { UINT Index; BOOLEAN bIsExist; UCHAR TagetHrdAddress[6]; }HrdAddress,*PHrdAddress; |
|
地下室#
发布于:2004-04-27 10:58
非常感谢
|
|