W5300 Ping 관련 문의합니다

W5300 제품을 사용하고 있습니다.

UDP/TCP 는 정상적으로 동작을 하는데 IPRAW 에서 Ping 관련 동작이 이상하여 문의합니다.

  1. 패킷을 덤프(Wireshark 사용)
    w5300 → PC
    |00|23|8b|b3|93|92|00|08|dc|00|00|64|08|00|45|00|00|3c|00|01|40|00|80|01|79|08|c0|a8|00|64
    |c0|a8|00|03
    |08|00|f8|06|12|34|43|21|61|62|63|64|65|66|67|68|69|6a|6b|6c|6d|6e|6f|70|71|72|73|74|75|76|77|61|62|63|64|65|66|67|68|69|
    PC → w5300
    |00|08|dc|00|00|64|00|23|8b|b3|93|92|08|00|45|00|00|3c|13|cd|40|00|80|01|65|3c|c0|a8|00|03
    |c0|a8|00|64
    |00|00|00|07|12|34|43|21|61|62|63|64|65|66|67|68|69|6a|6b|6c|6d|6e|6f|70|71|72|73|74|75|76|77|61|62|63|64|65|66|67|68|69|

  2. w5300 보드에서 디버크포트를 사용하여 프린트해본 결과
    IP RAW msg arrived
    source IP : 192.168.0.3
    [ICMP] 40Byte
    0xC0 0x00 0x00 0x07 0x12 0x34 0x43 0x21 0x61 0x62
    0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6A 0x6B 0x6C
    0x6D 0x6E 0x6F 0x70 0x71 0x72 0x73 0x74 0x75 0x76
    0x77 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69

  • w5300에서 ping(SOCK_IPRAW 모드) 실행시에 PC에서 정상적으로 reply하는 것을 보면
    ping request는 정상적으로 되는것 같습니다.
    그런데, 타겟에서 recvfrom 함수로 수신하는 데이터의 ICMP Type부분만 항상 이상하게 올라옵니다.
    (0xC0 말고도 다른값도 올라옵니다)

  • Config

  1. DEF_IINCHIP_DIRECT_MODE 로 사용
  2. 8bit 모드로 사용하고 있습니다.

검토 부탁드립니다.

W5300의 IPRAW Mode의 수신 Data Format은 아래와 같습니다.
Destiontion IP | Data Length | Data
Destionation IP와 Data Length 부분이 제대로 처리되는지 확인 부탁드립니다.

Wireshark 원본을 보내주셔야 분석에 도움이되며,
IPRAW 에서 수신한 Buffer를 처리하기 전 Raw Data를 Dump 해서 올려주세요.

  1. 패킷을 덤프(Wireshark 사용)
  • 화일 첨부하는 부분이 없어서 다시 보냅니다.(샤크에서 텍스트화일로 저장했을때 덤프화면입니다.)
  • w5300(IP : 192.168.0.100, Mac:00:08:dc:00:00:64)
  • PC(IP : 192.168.0.3, Mac:00:23:8b:b3:93:92)
    ±--------±--------------±---------+
    03:57:24,411,129 ETHER
    |00|23|8b|b3|93|92|00|08|dc|00|00|64
    |08|00|45|00|00|3c|00|01|40|00|80|01|79|08
    |c0|a8|00|64|c0|a8|00|03
    |08|00|f8|06|12|34|43|21
    |61|62|63|64|65|66|67|68|69|6a|6b|6c|6d|6e|6f
    |70|71|72|73|74|75|76|77|61|62|63|64|65|66|67|68|69|
    ±--------±--------------±---------+
    03:57:24,411,145 ETHER
    |00|08|dc|00|00|64|00|23|8b|b3|93|92
    |08|00|45|00|00|3c|13|cb|40|00|80|01|65|3e
    |c0|a8|00|03|c0|a8|00|64
    |00|00|00|07|12|34|43|21
    |61|62|63|64|65|66|67|68|69|6a|6b|6c|6d|6e|6f
    |70|71|72|73|74|75|76|77|61|62|63|64|65|66|67|68|69|
  1. w5300 보드에서 디버크포트를 사용하여 프린트해본 결과
    IP RAW msg arrived
    Source IP : 192.168.0.3
  • 위의 부분은 귀사에서 제공되는 소스 중 socket.c 화일의 recvfrom 함수에서 프린트하는 부분입니다.(socket.c 화일 첨부)
    recvfrom 함수내에 data_len(변수) 리턴하는 값을 프린트했을 경우 40byte로 Length 부분도 정상적으로 수신됩니다.
    => Type(1byte) + Code(1byte) + Checksum(2byte) + Id(2byte) +SeqNum(2byte) + Data(32Byte)

  • 리턴하는 데이터값을 프린트 했을 경우가 아래와 같은 경우입니다.(자체 디버그)
    제일 처음 나오는 Type 부분이 이상한 값으로 됩니다.
    [ICMP] 40Byte(data_len)
    => Type(1byte) + Code(1byte) + Checksum(2byte) + Id(2byte) +SeqNum(2byte) + Data(32Byte) : 40byte
    0xC0 0x00 0x00 0x07 0x12 0x34 0x43 0x21 0x61 0x62
    0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6A 0x6B 0x6C
    0x6D 0x6E 0x6F 0x70 0x71 0x72 0x73 0x74 0x75 0x76
    0x77 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69

  1. socket.c 화일입니다(첨부하는 방법을 몰라서 화일을 그대로 올립니다. 양해바랍니다.)
    아래소스중 recv_from함수 참조바랍니다.
    #include “main.h”

#define SWAP16(A) ((((A << 8 ) & 0xFF00)) | ((A >> 8)& 0x00FF))

u16 iinchip_source_port;
u8 check_sendok_flag[MAX_SOCK_NUM];

u8 socket(SOCKET s, u8 protocol, u16 port, u16 flag)
{
IINCHIP_WRITE(Sn_MR0(s), (u8)((protocol | flag) >> 8));
IINCHIP_WRITE(Sn_MR1(s), (u8)((protocol | flag) & 0xff));
if (port != 0)
{
IINCHIP_WRITE(Sn_PORTR0(s),(u8)((port & 0xff00) >> 8));
IINCHIP_WRITE(Sn_PORTR1(s),(u8)(port & 0x00ff));
}
else
{
iinchip_source_port++; // if don’t set the source port, set local_port number.
IINCHIP_WRITE(Sn_PORTR0(s),(u8)((iinchip_source_port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_PORTR1(s)),(u8)(iinchip_source_port & 0x00ff));
}
setSn_CR(s, Sn_CR_OPEN); // open s-th SOCKET

check_sendok_flag[s] = 1; // initialize the sendok flag.

#if 0
printf(“[NET] Ch%d : Sn_MR=0x%04x,Sn_PORTR=0x%04x(%04d),Sn_SSR=%04x\r\n”,s,IINCHIP_READ(Sn_MR(s)),(u16)((IINCHIP_READ(Sn_PORTR0(s)) << 8) + IINCHIP_READ(Sn_PORTR1(s))),(u16)((IINCHIP_READ(Sn_PORTR0(s)) << 8) + IINCHIP_READ(Sn_PORTR1(s))),getSn_SSR(s));
#endif
return 1;
}

void close(SOCKET s)
{
// M_08082008 : It is fixed the problem that Sn_SSR cannot be changed a undefined value to the defined value.
// Refer to Errata of W5300
//Check if the transmit data is remained or not.
if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getIINCHIP_TxMAX(s)) )
{
u16 loop_cnt =0;
while(getSn_TX_FSR(s) != getIINCHIP_TxMAX(s))
{
if(loop_cnt++ > 10)
{
u8 destip[4];
// M_11252008 : modify dest ip address
//getSIPR(destip);
destip[0] = 0;destip[1] = 0;destip[2] = 0;destip[3] = 1;
socket(s,Sn_MR_UDP,0x3000,0);
sendto(s,(u8*)“x”,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
break; // M_11252008 : added break statement
}
Delay(10);
}
};
setSn_IR(s ,0x00FF); // Clear the remained interrupt bits.
setSn_CR(s ,Sn_CR_CLOSE); // Close s-th SOCKET
}

u8 connect(SOCKET s, u8 * addr, u16 port)
{
if
(
((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
(port == 0x00)
)
{
#ifdef NETDEBUG
printf(“[NET] Ch%d : Fail[Invalid IP, PORT]\r\n”,s);
#endif
return 0;
}

// set destination IP 
//IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
//IINCHIP_WRITE(Sn_DIPR1(s),addr[1]);
//IINCHIP_WRITE(Sn_DIPR2(s),addr[2]);
//IINCHIP_WRITE(Sn_DIPR3(s),addr[3]);	
// set destination port number
//IINCHIP_WRITE(Sn_DPORTR0(s),(((u8)port >> 8)));
//IINCHIP_WRITE(Sn_DPORTR1(s),(((u8)port & 0xff)));
setSn_DIPR(s, &addr[0]);
setSn_DPORTR(s, port);
// Connect
setSn_CR(s,Sn_CR_CONNECT);

return 1;
}

void disconnect(SOCKET s)
{
setSn_CR(s,Sn_CR_DISCON); // Disconnect
}

u8 listen(SOCKET s)
{
if (getSn_SSR(s) != SOCK_INIT)
{
#if 0
printf(“[NET] Ch%d : SOCKET is Not Created.\n”,s);
#endif
return 0;
}
setSn_CR(s,Sn_CR_LISTEN); // listen

return 1;
}

u32 send(SOCKET s, u8 * buf, u32 len)
{
u8 status=0;
u32 ret=0;
u32 freesize=0;
#if 0
u32 loopcnt = 0;

  printf("%d : send()\r\n",s);

#endif

ret = len;
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.

/*
* \note if you want to use non blocking function, “do{}while(freesize < ret)” code block
* can be replaced with the below code. \n
* \code
* while((freesize = getSn_TX_FSR(s))==0);
* ret = freesize;
* \endcode
/
// -----------------------
// NOTE : CODE BLOCK START
do
{
freesize = getSn_TX_FSR(s);
status = getSn_SSR(s);
#if 0
printf(“%d : freesize=%ld\r\n”,s,freesize);
if(loopcnt++ > 0x0010000)
{
printf(“%d : freesize=%ld,status=%04x\r\n”,s,freesize,status);
printf(“%d:Send Size=%08lx(%d)\r\n”,s,ret,ret);
printf(“MR=%04x\r\n”,
((vuint16*)MR));
loopcnt = 0;
}
#endif
if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT)) return 0;
} while (freesize < ret);
// NOTE : CODE BLOCK END
// ---------------------

 if(ret & 0x01) wiz_write_buf(s, buf, (ret+1));
 else wiz_write_buf(s,buf,ret);                   // copy data

#if 0
loopcnt=0;
#endif

if(!check_sendok_flag[s]) // if first send, skip.
{
while (!(getSn_IR(s) & Sn_IR_SENDOK)) // wait previous SEND command completion.
{
#if 0

     if(loopcnt++ > 0x010000)
     {
        printf("%d:Sn_SSR(%02x)\n",s,status);
        printf("%d:Send Size=%08lx(%d)\n",s,ret,ret);
        printf("MR=%02x%02x\n",*((volatile unsigned char*)MR0),*((volatile unsigned char*)MR1));
        loopcnt = 0;
     }
  #endif
     if (getSn_SSR(s) == SOCK_CLOSED)    // check timeout or abnormal closed.
     {
        #ifdef NET_DEBUG
           printf("%d : Send Fail. SOCK_CLOSED.\r\n",s);
        #endif
        return 0;
     }
  }
  setSn_IR(s, Sn_IR_SENDOK);             // clear Sn_IR_SENDOK      

}
else check_sendok_flag[s] = 0;

// send
setSn_TX_WRSR(s,ret);
setSn_CR(s,Sn_CR_SEND);

return ret;
}

u32 recv(SOCKET s, u8 * buf, u32 len)
{
u16 pack_size=0;
vint16 mr = getMR();

#if 0
printf(“%d : recv()\r\n”,s);
#endif

if(IINCHIP_READ(Sn_MR0(s)) & Sn_MR_ALIGN)
{
wiz_read_buf(s, buf, len);
setSn_CR(s,Sn_CR_RECV);
return len;
}

wiz_read_buf(s,(u8*)&pack_size,2); // extract the PACKET-INFO(DATA packet length)

 #ifdef LITTLE_ENDIAN
 		if(mr & MR_FS) pack_size = pack_size;
 		else pack_size = SWAP16(pack_size);
 #else
 		if(mr & MR_FS) pack_size = SWAP16(pack_size);
 		else pack_size = pack_size;

#endif

#if 0
printf(“%d:pack_size=%d\r\n”,s,pack_size);
#endif

len = pack_size;
if(pack_size & 0x01) len += 1;

wiz_read_buf(s, buf, len); // copy data

setSn_CR(s,Sn_CR_RECV); // recv

/*

  • \warning send a packet for updating window size. This code block must be only used when W5300 do only receiving data.
    */
    // ------------------------
    // WARNING CODE BLOCK START

// M_15052008 : Replace Sn_CR_SEND with Sn_CR_SEND_KEEP.
//if(!(getSn_IR(s) & Sn_IR_SENDOK))
//{
// setSn_TX_WRSR(s,0); // size = 0
// setSn_CR(s,Sn_CR_SEND); // send
// while(!(getSn_IR(s) & Sn_IR_SENDOK)); // wait SEND command completion
// setSn_IR(s,Sn_IR_SENDOK); // clear Sn_IR_SENDOK bit
//}

// M_04072008 : Replace Sn_CR_SEND_KEEP with Sn_CR_SEND.
//if(getSn_RX_RSR(s) == 0) // send the window-update packet when the window size is full
//{
// u8 keep_time = 0;
// if((keep_time=getSn_KPALVTR(s)) != 0x00) setSn_KPALVTR(s,0x00); // disables the auto-keep-alive-process
// setSn_CR(s,Sn_CR_SEND_KEEP); // send a keep-alive packet by command
// setSn_KPALVTR(s,keep_time); // restore the previous keep-alive-timer value
//}

// if(getSn_RX_RSR(s) == 0) // check if the window size is full or not
// { /* Sn_RX_RSR can be compared with another value instead of ??0??,
// according to the host performance of receiving data */
// setSn_TX_WRSR(s,1); // size : 1 byte dummy size
// IINCHIP_WRITE(Sn_TX_FIFOR0(s),0x00); // write dummy data into tx memory
// IINCHIP_WRITE(Sn_TX_FIFOR1(s),0x00);
// setSn_CR(s,Sn_CR_SEND); // send
// while(!(getSn_IR(s) & Sn_IR_SENDOK)); // wait SEND command completion
// setSn_IR(s,Sn_IR_SENDOK); // clear Sn_IR_SENDOK bit
// }

// WARNING CODE BLOCK END
// ----------------------

return (u32)pack_size;
}

u32 sendto(SOCKET s, u8 * buf, u32 len, u8 * addr, u16 port)
{
u8 status=0;
u8 isr=0;
u32 ret=0;

#if 0
printf(“%d : sendto():%d.%d.%d.%d(%d), len=%d\r\n”,s, addr[0], addr[1], addr[2], addr[3] , port, len);
#endif

if
(
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
((port == 0x00)) ||(len == 0)
)
{
#if 0
printf(“%d : Fail[%d.%d.%d.%d, %.d, %d]\r\n”,s, addr[0], addr[1], addr[2], addr[3] , port, len);
#endif
return 0;
}

if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;

// set destination IP address
IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
IINCHIP_WRITE(Sn_DIPR1(s),addr[1]);
IINCHIP_WRITE(Sn_DIPR2(s),addr[2]);
IINCHIP_WRITE(Sn_DIPR3(s),addr[3]);
// set destination port number
IINCHIP_WRITE(Sn_DPORTR0(s),((u8)(port >> 8)));
IINCHIP_WRITE(Sn_DPORTR1(s),((u8)(port & 0xff)));

/* BIBALAM */
// W5300 Access Fail
//printf("[SOCKET] Buf Addr[0x%X]\n", &buf[0]);	
//getSn_SSR(0); //Dummy Read
/* BIBALAM */

wiz_write_buf(s, buf, ret+(ret & 0x01)); // copy data
// send
setSn_TX_WRSR(s,ret);
setSn_CR(s, Sn_CR_SEND);

while (!((isr = getSn_IR(s)) & Sn_IR_SENDOK)) // wait SEND command completion
{
status = getSn_SSR(s); // warning ---------------------------------------
if ((status == SOCK_CLOSED) || (isr & Sn_IR_TIMEOUT)) // Sn_IR_TIMEOUT causes the decrement of Sn_TX_FSR
{ // -----------------------------------------------
#if 0
printf(“%d: send fail.status=0x%02x,isr=%02x\r\n”,s,status,isr);
#endif
setSn_IR(s,Sn_IR_TIMEOUT);
return 0;
}
}
setSn_IR(s, Sn_IR_SENDOK); // Clear Sn_IR_SENDOK

#if 0
printf(“%d : send()end\r\n”,s);
#endif

return ret;
}

u32 recvfrom(SOCKET s, u8 * buf, u32 len, u8 * addr, u16 *port)
{
u8 head[8];
u16 data_len=0;
u16 crc[2];
vint16 mr = getMR();
u16 i, Data;
#if 0
printf(“recvfrom()\r\n”);
#endif

if ( len > 0 )
{

  switch (IINCHIP_READ(Sn_MR1(s)) & 0x07)       // check the mode of s-th SOCKET
  {                                            // -----------------------------
     case Sn_MR_UDP :                          // UDP mode 
     
        wiz_read_buf(s, head, 8);      // extract the PACKET-INFO
        // read peer's IP address, port number.
   
        if(mr & MR_FS)
        {
        	addr[0] = head[1];       // destination IP address
        	addr[1] = head[0];
        	addr[2] = head[3];
        	addr[3] = head[2];
        }
        else
        {
        	addr[0] = head[0];
        	addr[1] = head[1];
        	addr[2] = head[2];
        	addr[3] = head[3];
        }
        #ifdef LITTLE_ENDIAN
        	if(mr & MR_FS)
        	{
        		*port = head[5];                     // destination port number
        		*port = (*port << 8) + head[4];
							data_len = (u16)head[7];			 		// DATA packet length
        		data_len = (data_len << 8) + head[6];
        	}
        	else
        	{
        		*port = head[4];                     // destination port number
        		*port = (*port << 8) + head[5];
        		data_len = (u16)head[6];					// DATA packet length
        		data_len = (data_len << 8) + head[7];
        	}
        #else
        	if(mr & MR_FS)
        	{
        		*port = head[4];
        		*port = (*port << 8) + head[5];
        		data_len = (u16)head[6];					// DATA packet length
        		data_len = (data_len << 8) + head[7];
        	}
        else
        	{
        		*port = head[5];
        		*port = (*port << 8) + head[4];
        		data_len = (u16)head[7];					// DATA packet length
        		data_len = (data_len << 8) + head[6];
        	}
        #endif
        
        #if	0
           printf("UDP msg arrived:%d(0x%04x)\r\n",data_len,data_len);
           printf("source Port : %d\r\n", *port);
           printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
        #endif

        wiz_read_buf(s, buf, data_len + (data_len & 0x01) );        // data copy.
        break;
                                               // -----------------------
     case Sn_MR_IPRAW :                        // IPRAW mode
        wiz_read_buf(s, (u8*)head, 6);      // extract the PACKET-INFO 
		
        if((*(vint8*)MR0) & MR_FS)
        {
        	addr[0] = head[1];						 // destination IP address
        	addr[1] = head[0];
        	addr[2] = head[3];
        	addr[3] = head[2];
        }
        else
        {
        	addr[0] = head[0];				     // destination IP address
        	addr[1] = head[1];
        	addr[2] = head[2];
        	addr[3] = head[3];
        }
        
        #ifdef LITTLE_ENDIAN
        	if((*(vint8*)MR0) & MR_FS)
        	{
        		data_len = (u16)head[5];				 // DATA packet length
       		 	data_len = (data_len << 8) + head[4];
       		 }
        	else
        	{
        		data_len = (u16)head[4];        // DATA packet length
        		data_len = (data_len << 8) + head[5];
        	}
        #else
        	if((*(vint8*)MR0) & MR_FS)
        	{
        		data_len = (u16)head[4];
        		data_len = (data_len << 8) + head[5];
        	}
        	else
        	{
        		data_len = (u16)head[5];
        		data_len = (data_len << 8) + head[4];
        	}
        #endif
        
        #if	1
           printf("IP RAW msg arrived\r\n");
           printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
        #endif
        
        wiz_read_buf(s, buf, data_len+(data_len & 0x01));        // data copy.

        break;                                 
                                               // -----------------------
     case Sn_MR_MACRAW :                       // MACRAW mode
        wiz_read_buf(s,(u8*)head,2);        // extract the PACKET-INFO
        #ifdef LITTLE_ENDIAN
        	if((*(vint8*)MR0) & MR_FS)
        	{
        		data_len = (u16)head[1];        // DATA packet length
        		data_len = (data_len << 8) + head[0];
        	}
        	else
        	{
        		data_len = (u16)head[0];
        		data_len = (data_len << 8) + head[1];
        	}
        #else
        	if((*(vint8*)MR0) & MR_FS)
        	{
        		data_len = (u16)head[0];
        		data_len = (data_len << 8) + head[1];
        	}
        	else
        	{
        		data_len = (u16)head[1];
        		data_len = (data_len << 8) + head[0];
        	}
        #endif
        
        wiz_read_buf(s, buf, data_len + (data_len & 0x01));        // data copy.
        wiz_read_buf(s,(u8*)crc, 4);        // extract CRC data and ignore it.

        break;
     default :
        break;
  }
  setSn_CR(s,Sn_CR_RECV);                      // recv

}
#if 0
printf(“recvfrom() end …\r\n”);
#endif

return data_len;
}

검토바랍니다.

W5300의 8bit Mode사용시 FIFOR을 읽는 중간에 다른 Register(MR 등)를 읽는 경우 잘못된 값을 읽을 수 있습니다.

recvfrom 함수에서 UDP는 처리가 되어 있는데, IPRAW와 MACRAW단은 처리가 되어 있지 않네요.

해당 사항은 수정후 WIZnet 홈페이지에 Upload 하겠습니다.

UDP 정상처리된 코드

switch (IINCHIP_READ(Sn_MR1(s)) & 0x07) // check the mode of s-th SOCKET
 { // -----------------------------
 case Sn_MR_UDP : // UDP mode 

 wiz_read_buf(s, head, 8); // extract the PACKET-INFO
 // read peer's IP address, port number.

 if(mr & MR_FS)
 {
 addr[0] = head[1]; // destination IP address
 addr[1] = head[0];
 addr[2] = head[3];
 addr[3] = head[2];
 }
case Sn_MR_IPRAW : // IPRAW mode
 wiz_read_buf(s, (u8*)head, 6); // extract the PACKET-INFO 

 if((*(vint8*)MR0) & MR_FS)  ///////<----- if(mr & MR_FS)
 {
 addr[0] = head[1]; // destination IP address
 addr[1] = head[0];
 addr[2] = head[3];
 addr[3] = head[2];
 }
 else
 {
 addr[0] = head[0]; // destination IP address
 addr[1] = head[1];
 addr[2] = head[2];
 addr[3] = head[3];
 }

MACRAW 코드 역시 수정이 필요합니다.

즉 recvfrom() 함수 내에서 MR 레지스트를 다이렉트로 보는 부분은 저장된 mr값으로 변경하셔야 합니다.

수정사항 적용해서 해보니 잘 올라오네요…

빠른답변 감사합니다.

그리고, UDP 통신할 경우 브로트캐스트 데이터 수신은 별도의 설정이 필요한지 궁금합니다.

감사합니다.

[url]http://www.wiznet.co.kr/sub_modules/en/product/product_detail.asp?Refid=681&page=1&cate1=5&cate2=7&cate3=25&pid=1012&cType=2[/url]

8bit 드라이버가 update되었습니다.

UDP Broadcast시 따로 설정할 필요는 없습니다. 디폴트로 Port 넘버가 같으면 브로드캐스트든 유니캐스트든 패킷을 수신학 되어있습니다.
Broadcast 패킷을 수신을 원치 않을 경우 Sn_MR Register의 BCASTB bit를 1로 설정하시면 브로드캐스트 패킷이 차단됩니다.