- 패킷을 덤프(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|
- 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
- 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;
}
검토바랍니다.