slobby
驱动牛犊
驱动牛犊
  • 注册日期2003-12-07
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3162回复:4

已经知道对方IP,如何通过IP得到他的Mac地址呢

楼主#
更多 发布于:2004-04-25 12:40
想在底层构建Packet发出去,但只知道他的IP,以太帧头不知到怎么填!
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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地址。
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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;
}
}
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于: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;
slobby
驱动牛犊
驱动牛犊
  • 注册日期2003-12-07
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-27 10:58
非常感谢
游客

返回顶部