Arp관련 질문있습니다

w5100이 하드웨어적으로 arp req를 하는걸로 알고 있습니다…
dest 정보가 틀릴때만요…

우선 w5100에서 소켓 2개를 사용합니다…
tcp 와 udp 2개를 사용을 하는데…

udp일때가 문제가 있습니다…

udp시, 브로드 캐스팅으로 데이터를 주고 받으면서 자체 프로토콜에 맞는 정보를 처리하는데요…

소켓상태가 SOCK_UDP 일시에 recv_from(); 함수로 데이터 길이와, dest ip, dest port를 알수 있자나요…
브로드 캐스팅 ip (255.255.255.255)로 send_to () 함수를 이용 데이터를 전송합니다… recv_from(); 함수에서 획득한 dest_ip를 사용하지 않고요…

근데 문제가 예를 들어서 어떤 커맨드 ""가 브로드 캐스팅으로 전송해 온다면, 그다음부턴 recv_from(); 함수에서 획득한
브로드 캐스팅 ip가 아닌 dest_ip를 사용을 하는데요 이때 문제가 있습니다… (사진 첨부) arp를 못하는거 같은데요…

다시 한번 설명을 드리면
pc— w5100---- rs232----장비 이렇게 연결되어 있습니다…
브로드 캐스팅으로는 w5100의 정보를 바꾸는데만 사용하고 있습니다…
브로드 캐스팅으로 정보를 주고 받다가, “” 이 커맨드를 pc측으로부터 수신을 받으면
w5100은 단지 터미널 모드로 사용합니다…

pc (192.168.0.10) 명령 전송 —> w5100 (pc 명령 232 장비측 전송)------> 장비 (pc 명령 수신 처리후 ack 보냄)
------> w5100 (232로 받은 장비 ack를 pc로 udp로 전송)

이런식으로 주고 받는데요…

이때 pc에서 보낸 명령이 w5100이 잘 받고 232를 통해 장비까지 전송되고 ack까지 받습니다…
이제 ack를 pc로 보낼때 문제가 있습니다… 그림을 보시면 아시겠지만…

조언 부탁드립니다… 급합니다…

void ProcessBcast (void)
{
	unsigned char data_buf[300];				
	unsigned int len, dest_port, i;
	unsigned long dest_ip = 0;

	switch (getSn_SR (nSocket2))
	{
		case SOCK_UDP:
			if ((len = getSn_RX_RSR (nSocket2)) > 0)
			{
				if (len > 300) len = 300;

				len = recvfrom (nSocket2, data_buf, len, (unsigned char *)&dest_ip, &dest_port);

				UDP_dPort = dest_port;

				if (UDP_Sel) {
					UDP_dIP = dest_ip;
				}

				if ((data_buf [len - 1] == LF) && (data_buf [0] == '<') && (data_buf [len - 2] == '>')) {
					Bcast_Proc (nSocket2, dest_ip, dest_port, data_buf);
				}
				else {
					for (i = 0; i < len; i++) 
						USART_Transmit (data_buf [i]);
				}
			}
			break;
		case SOCK_CLOSED:
			close (nSocket2);
			socket (nSocket2, Sn_MR_UDP, Bcast_Port, 0x00);
			break;

	}
}

ISR (TIMER0_OVF_vect)			// 0.998mS Timer
{
	if (sys_tickS) {
		if (sys_tick++ == 1) {			
			sys_tickS = 0;

			if (UDP_Sel) 
				sendto (nSocket2, rx0_buf, rx0_bCnt, (unsigned char *)&UDP_dIP, UDP_dPort); 
			
			else
				send(nSocket, rx0_buf, rx0_bCnt);

			rx0_bCnt = 0;
		}
	}
	TCNT0 = 26;
}


설명으로 봐서는
PC 192.168.0.10
W5100 : 192.168.0.2
인것 같네요.

근데 W5100이 192.168.0.10으로 ARP를 보내는 것이 아니라, 192.168.0.1로 보내고 있습니다.
혹시 192.168.0.1 이 Gateway IP 주소라면, PC와 W5100의 Subnet Mask가 서로 다르게 설정되어 있어 다른 망으로 인식되어 Gateway로 ARP를 요청할 수 있습니다.
192.168.0.1 이 Gateway IP 주소가 아니라면, Destination IP가 192.168.0.1로 잘못 설정되었는지 확인하시기 바랍니다.

pc 네트웍 정보는
ip 192.168.0.10
subnet 255.255.255.0
gateway 설정 x

w5100
ip 192.168.0.2 subnet 255.255.255.0 gateway 192.168.0.1 port 5000 로 설정되어 있구요…

예를들어서…

volatile unsigned long dest_ip2; // global var
volatile unsigned int dest_port2; // global var

len = recvfrom (nSocket2, data_buf, len, (unsigned char *)&dest_ip, &dest_port);
recv_from (); 함수로 획득한 destination ip와 port를
dest_ip2 = dest_ip;
dest_port2 = dest_port; 전역변수에 저장한후에…

장비측으로 232 데이터를 전송하고… (w5100 → serial → 장비);

장비측에서의 보낸 ack를 w5100에서 수신하면 바로… (장비 → serial → w5100)

sendto (nSocket2, rx0_buf, rx0_bCnt, (unsigned char *)&dest_ip2, port2); 전송…

recv_from (); 에서 획득한 destination ip와 port로 전송을 하는거 밖에 없습니다…

또 이게… 될때가 있고… 저렇게 arp 뜰때가 있고요…

ARP request를 192.168.0.1로 보내는 경우는 두가지가 있습니다.

  1. 위의 midnightcow님이 얘기한 것 처럼, Subnet mask 오류로 192.168.0.10을 외부망으로 인식한 경우, 자신(W5100)에 등록된 Gateway로 ARP request를 보냅니다.
  2. 192.168.0.10으로 전송한 것으로 생각하지만 실제로는 192.168.0.1로 전송을 한 경우입니다.

Subnet mask를 255.255.255.0 으로 설정했다면 1번의 경우는 해당 사항이 없어 보입니다.
2번의 경우도 수신한 dest_ip, dest_port 값을 전역변수 dest_ip2, dest_port2에 저장했다가 사용하셨다고 하는데, 전역변수에 저장하기 전, sendto() 함수를 호출하기 전에 dest_ip, dest_port 값과 dest_ip2, dest_port2의 실제값을 debug로 출력해서 확인해 볼 필요가 있다고 봅니다.

ip를 확인해 보니 제대로 192.168.0.10으로 되어 있군요…

흠…

혹시 처음에 udp를 브로드 캐스팅 으로 (255.255.255.255)로 사용하다가 일반 udp로 사용하자나요…
이때 pc에서 연결을 끊고 다시 연결해서 사용해야 하는건가요?? udp라 별 상관 없을거 같은데요…ㅠ
흠…

제가 알기로는 Unicast든 Broadcast든 송수신은 W5100이든 PC든 상관없이 되는 걸로 알고 있습니다.

Destination IP를 실제 Memory 순서대로 출력하여 보시는 것인지 궁금합니다.
사용하시는 변수가 Byte array가 아닌 long type 변수인걸로 보아, system-endian 문제가 발생한 것일수도 있습니다.
W5100의 모든 Register들은 Big-endian 방식으로 저장됩니다.

예로) Dest IP register address 0x1000 이고 저장될 IP가 192.168.1.100 이라면
*(0x1000) = 192;
*(0x1001) = 168;
*(0x1002) = 1;
*(0x1003) = 100;

실제 Endian 문제가 있을 경우 W5100은 입력한 아이피를 100.1.168.192로 인식하여 gateway로 arp를 보내게 됩니다.

그건 저도 알고 있습니다…
디버그 모드로 해서 동작을 실행 시켜보앗습니다… 한번 보시죠…

UDP msg arrived
source Port : 1820
source IP : 192.168.0.10
sendto(OK
.168.0.2,258)
[ch0][255.255.255.255, 1820, 3]
UDP msg arrived

[color=#FF0000]source Port : 1820
source IP : 192.168.0.10
/U?
sendto(/B
)

[ch0][192.168.000.010, 1820, 3]
send fail.[/color]

보시면…
브로드 캐스팅으로 받고 수신후 제가 거기에 대한 응답후

그후 udp로 “/U?” 이걸 보내면 w5100으로 보내면 저는 “/B” 이걸 보냅니다…
그밑에 보면 dest_ip 와, port, len을 알수 있고요…
전송 실패가 뜨고요…

이게 전송이 잘될때가 있고 안될때가 있어서 문제라는 거구요…

W5100 드라이브 코드를 공유하실 수 있나요?

전체 소스를 말하는건가요?? 아니면
w5100 드라이버 소스만 말씀하시는건가요??
메일 주소를 알려주시면 그쪽으로 보내드리겠습니다…

드라이브 소스를 “Code” 기능을 이용해서 여기 포럼에 올려주세요.

최소한 sendto() 함수와 recvfrom() 함수.
다른 분 중에도 코멘트하실 분들이 있을 수 있으니…

sendto , recvfrom () 함수는 라이브러리 그대로 쓴거고요…

자체 프로토콜에서 브로드캐스팅하다가 “” 커맨드 받으면 일반 udp로 사용하는거 밖에 없습니다…
udp_sel = 1 이면 destination ip를 UDP_dIP에 저장한다음 232 데이터를 전체 수신한후 1ms 지나서 전송

통신속도가 38400 bps이기때문에 충분하고요…1ms면…