FPGA로 어떻게 제어하시는지는 모르겠습니다만.
mcu처럼 쓰고 계시는 건지요?
ARP request packet을 data로 만든 후 send 명령을 W5300에 보내시면 됩니다.
ARP request packet은 wireshark 프로그램을 이용하여 패킷캡쳐를 통해 보실 수 있습니다.
그런형태의 data를 send 하시면 arp reply packet이 오게 됩니다.
해당 Data를 recv하신 다음 data를 parsing 하시면 destination의 Mac address를 알 수 있게 됩니다.
아래 S/W코드를 참고 하시기 바랍니다. (W5300이 아닌 다른 칩의 firmware니 그대로 쓰시면 안됩니다.)
uint32_t arp_request_send(uint8_t * target_ip)
{
int32_t ret;
uint8_t i;
uint8_t smac[6] = {0,0,0,0,0,0};
uint8_t sip[4] = {0,0,0,0};
uint8_t arp_packet[42] = {0,};
switch(getSn_SR(0))
{
case SOCK_MACRAW :
/*Destination MAC Address field*/
for(i=0; i<6; i++)
{
arp_packet[i] = 0xff;
}
/*get Source Mac Address*/
getSHAR(smac);
/*Source Mac Address field*/
for(i=6; i<12; i++)
{
arp_packet[i] = smac[i-6];
}
/*Ether Type field*/
arp_packet[12] = 0x08; arp_packet[13] = 0x06;//Ether Type : ARP 0x0806
/*ARP field*/
arp_packet[14] = 0x00; arp_packet[15] = 0x01;//Hardware Type : Ethernet 0x0001
arp_packet[16] = 0x08; arp_packet[17] = 0x00;//Protocol Type : IPv4 0x0800
arp_packet[18] = 0x06;//Hardware Size : 0x0006
arp_packet[19] = 0x04;//Protocol Size : 0x0004
arp_packet[20] = 0x00; arp_packet[21] = 0x01;//OPcode : Request 0x0001
/*Source Mac address field*/
for(i=22; i<28; i++)
{
arp_packet[i] = smac[i-22];
}
/*get Source IP Address*/
getSIPR(sip);
/*Source IP address field*/
for(i=28; i<32; i++)
{
arp_packet[i] = sip[i-28];
}
/*Target Mac address field*/
for(i=32; i<38; i++)
{
arp_packet[i] = 0x00;//Target MAC : 00:00:00:00:00:00
}
/*Target IP address field*/
for(i=38; i<42; i++)
{
arp_packet[i] = target_ip[i-38];
}
ret = sendto(0, arp_packet, sizeof(arp_packet), 0, 0); // arp packet send
return ret;
default :
printf("Error : macraw socket not open\r\n");
return -1;
}
}
int32_t arp_reply_recv(uint8_t * target_ip)
{
int32_t ret;
uint8_t i;
uint8_t dst_mac[6]; // request source mac
uint8_t src_mac[6]; // request target mac
//uint16_t ether_type = 0;
//uint16_t hardware_type;
//uint16_t protocol_type;
//uint8_t hardware_size;
//uint8_t Protocol_size;
uint16_t size, opcode;
uint8_t source_ip[4] = {0,0,0,0}; // request target ip
//uint8_t target_ip[4] = {0,0,0,0}; // request source ip
switch(getSn_SR(0))
{
case SOCK_MACRAW :
if((size = getSn_RX_RSR(0)) > 0)
{
ret = recvfrom(0, ethBuf0, size, 0, 0);
if(ret <= 0)
{
printf("recvfrom error. %ld\r\n",ret);
return ret;
}
else
{
getSHAR(dst_mac);
if(dst_mac[0]!=ethBuf0[0] | dst_mac[1]!=ethBuf0[1] | dst_mac[2]!=ethBuf0[2] | dst_mac[3]!=ethBuf0[3] | dst_mac[4]!=ethBuf0[4] | dst_mac[5]!=ethBuf0[5])
{
printf("this packet is not my mac packet.\r\n");
return -1;//no mymac error
}
if(ethBuf0[12]!=0x08 | ethBuf0[13]!=0x06) //ether type ARP: 0x0806
{
printf("this packet is not arp packet.\r\n");
return -2;//no arp error
}
if(ethBuf0[20]!=0x00 | ethBuf0[21]!=0x02) //opcode reply : 0x0002
{
printf("this packet is not arp reply packet.\r\n");
return -3;//no arp reply error
}
for(i=22; i<28; i++)
src_mac[i-22] = ethBuf0[i];
for(i=28; i<32; i++)
source_ip[i-28] = ethBuf0[i];
if(source_ip[0]==target_ip[0] & source_ip[1]==target_ip[1] & source_ip[2]==target_ip[2] & source_ip[3]==target_ip[3])
{
printf("RECV ARP packet from %2x:%2x:%2x:%2x:%2x:%2x\r\n",src_mac[0],src_mac[1],src_mac[2],src_mac[3],src_mac[4],src_mac[5]);
printf("RECV ARP packet from %3d.%3d.%3d.%3d\r\n",source_ip[0],source_ip[1],source_ip[2],source_ip[3]);
return 0;
}
}
}
return 0;
default :
printf("Error : macraw socket not open\r\n");
return -1;
}
}
main(){
//MACRAW ARP scenario
setSn_MR2(0, Sn_MR2_BBLOCK|Sn_MR2_MBLOCK|Sn_MR2_6BLOCK);
printf(“Sn_MR2 register value : %x \r\n”,getSn_MR2(0));
while(1)
{
switch(getSn_SR(0))
{
case SOCK_MACRAW :
arp_reply_recv(WIZ_Dest_IP);
break;
case SOCK_CLOSED:
printf("in CLOSED\r\n");
if((ret = socket(0, Sn_MR_MACRAW, 0, Sn_MR_MFEN)) != 0)
return ret;
//setSn_MR2(0, /*Sn_MR2_BBLOCK|*/Sn_MR2_MBLOCK/*|Sn_MR2_6BLOCK*/);
printf("Opened, MACRAW Recv TEST\r\n");
arp_request_send(WIZ_Dest_IP);
break;
default :
printf("Error : macraw socket not open");
break;
}
}
//MACRAW recv scenario
setSn_MR2(0, Sn_MR2_BBLOCK|Sn_MR2_MBLOCK|Sn_MR2_6BLOCK);
printf("Sn_MR2 register value : %x \r\n",getSn_MR2(0));
while(1)
{
switch(getSn_SR(0))
{
case SOCK_MACRAW :
if((size = getSn_RX_RSR(0)) > 0)
{
printf("[RECV_DATA_LEN]:%d\r\n",size);
ret = recvfrom(0, ethBuf0, size, 0, 5000);
if(ret <= 0)
return ret;
}
break;
case SOCK_CLOSED:
printf("in CLOSED\r\n");
if((ret = socket(0, Sn_MR_MACRAW, 0, Sn_MR_MFEN)) != 0)
return ret;
printf("Opened, MACRAW Recv TEST\r\n");
break;
default :
printf("Error : macraw socket not open");
break;
}
}
}
감사합니다.