2012-08-07 3 views
0

데비안 6 상자에 여러 개의 물리적 네트워크 인터페이스가 있고, 각기 다른 서브넷 IP 주소를 가지고 있습니다. 두 개의 인터페이스는 스위치 허브에 연결되어 서로 통신 할 수 있습니다. 나는 2 개의 인터페이스 사이에 TCP 연결을 설정하려고합니다.netstat가 잘못된 외부 주소를 표시하는 이유

이것은 내가하는 일입니다. 먼저 SOCK_STREAM 소켓을 얻습니다. 그런 다음 setsockopt (..., SO_BINDTODEVICE, ...)를 사용하여 소켓을 특정 인터페이스 eth4에 바인드합니다. 그런 다음 sockaddr_in 구조를 설정하고 해당 인터페이스 (eth4)의 포트 및 주소로 채 웁니다. 그런 다음 bind()를 호출하여 해당 로컬 주소/포트를 소켓에 바인딩합니다. 그런 다음 accept() 다음에 listen()을 수행합니다. 들어오는 연결 요청을 기다리는 것을 차단합니다. 이 시점에서 나는 netstat을 할 수 있으며 정확히 내가 기대하는 것을 보여줍니다. 즉, 소켓이 실제로 LISTEN 상태이고 로컬 주소가 eth4 주소와 포트를 올바르게 보여줍니다.

다음 별도의 프로그램에서 소켓을 가져 오는 루틴이 있고 setsockopt (..., SO_BINDTODEVICE, ...)를 사용하여 소켓을 다른 인터페이스 인 eth5에 바인딩합니다. 그런 다음 eth4 인터페이스에 사용 된 포트 번호와 eth4 인터페이스의 주소를 사용하여 sockaddr_in 구조를 설정합니다. 나는 connect()를한다. 모든 것이 잘 진행되고 연결이 성공하며 실제로 두 개의 프로세스가이 TCP 연결과 연결되어 있음을 나타냅니다.

그러나 netstat을 실행하면 연결된 2 개의 PID/프로그램이 표시되지만 로컬 주소와 외부 주소가 모두 eth4에서 동일한 주소로 표시됩니다. eth5.

그래서 내 질문에 netstat 연결의 양쪽에 대해 동일한 주소를 표시합니까?

내가 말할 수있는 유일한 설명은 kernal이 연결 대상 주소가 실제로 로컬임을 인식하고 SO_BINDTODEVICE 바인딩을 무시하고 실제로 eth5에 연결하여 eth4에 연결하는 대신 내부적으로 TCP 연결을 만듭니다.

맞다면 동일한 리눅스 박스에있는 두 개의 분리 된 인터페이스 사이에서 어떻게 실제로 TCP 연결을 만들지 만 실제로 내부 연결 대신 외부 연결을할까요?

-Andres

당신이 사용하려는 나가는 인터페이스 (eth5)의 특정 IP 주소와 연결하기 위해 클라이언트의 소켓 connect 전에 bind를 호출 시도 할 수

답변

0

은 (포트가 있기 때문에, 0으로 설정 될 수있다 클라이언트의 경우이 경우 중요하지 않음). 이 방법은 SO_BINDTODEVICE 옵션을 사용하는 대신 사용할 수 있습니다.

나는이 옵션을 설정하는 몇 가지 방법을 제공하는 게시물을 발견했다 (http://stackoverflow.com/a/6566111/276274). 첫 번째는 장치 이름을 사용하여 setsockopt에 문자열을 전달하고 다른 하나는 인터페이스 색인이 ioctl을 통해 채워진 struct ifreq을 전달합니다. 인터페이스 색인을 사용하여 두 번째 탐색을 시도 할 수 있습니다.

또 다른 잠재적 인 문제는이 옵션을 설정하면 루트 권한이 필요하다는 것입니다.

옵션을 설정하는 위치에 코드 스 니펫을 게시 할 수 있다면 도움이 될 수 있습니다.

+0

답변 해 주셔서 감사합니다. –

관련 문제