2013-07-05 5 views
4

은 내가 소켓라우터가 내 패킷을 전달하지 않는 이유는 무엇입니까?

int s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); 

을 만들어 내 데이터가 포함되어 있기 때문에 나를 위해 IP 헤더를 기입하지 커널에게,

먼저 컴퓨터 A에 컴퓨터 B에서 TCP 패킷을 보내 원시 소켓을 사용 IP 헤더와 TCP 헤더

int optval = 1; 
setsockopt(s, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval)); 

설정하고 목적지 주소를 모두

struct sockaddr_in addr; 
memset(&addr, 0, sizeof(addr)); 
addr.sin_family = AF_INET; 
addr.sin_port = htons(33333); 
addr.sin_addr.s_addr = inet_addr("192.168.200.135"); 

전송할 데이터

sendto(s, data, len, 0, (struct sockaddr*)&addr, sizeof(addr)); 

내 네트워크 환경에서 케이스 (A)에 network environment

아래 그림과 같이하고, 두 시스템은 스위치로 연결된다. 사례 B에서 컴퓨터 B는 라우터에 연결하고 라우터는 스위치에 연결합니다.

내 프로그램은 케이스 A에서 제대로 작동합니다. 원시 소켓을 사용하여 컴퓨터 A에서 패킷을 수신하고 wireshark를 사용하여 해당 패킷을 캡처 할 수 있습니다.

사례 B에서는 컴퓨터 B에서 컴퓨터 A로 ping하고 B에서 A로 ssh 할 수 있습니다. 그리고 컴퓨터 A에서 원시 소켓과 wireshark를 모두 사용하여 B와 A 사이에서 전송 된 일부 TCP 패킷을 캡처 할 수 있습니다. 컴퓨터 B의 원시 소켓에서 보낸 패킷은 A에서 캡처 할 수 없습니다. 라우터가 내 패킷을 전달하지 않는 것으로 보입니다. 내 패킷에 문제가 있습니까? 다음과 같이 패킷 데이터와

내 전송 프로그램입니다 :

//data to send 
char data[48] = 
{ 
    //iphdr: 
    0x45, 0x00, 0x00, 0x30, //version:4 header_length:5 TOS:0 length:0x30 
    0x00, 0x01, 0x00, 0x00, //identification:1 flags:0 fragment_offset:0 
    0x40, 0x06, 0x2f, 0x47, //TTL:0x40 protocol:6(TCP) header_checksum:0x2f47 
    0xc0, 0xa8, 0x01, 0xa8, //source_IP:192.168.1.168 
    0xc0, 0xa8, 0xc8, 0x87, //destination_IP:192.168.200.135 
    //tcphdr: 
    0x56, 0xce, 0x82, 0x35, //source_port:22222 destination_port:33333 
    0x00, 0x00, 0x00, 0x00, //sequence_number:0 
    0x00, 0x00, 0x00, 0x00, //ack_number:0 
    0x50, 0x00, 0xaa, 0xaa, //header_length:5 window_size:0xaaaa 
    0xeb, 0xbd, 0x00, 0x00, //checksum:0xebbd urgent_pointer:0 
    //tcp content: 
    0x7a, 0x68, 0x73, 0x00, 
    0x39, 0x30, 0xce, 0x56, 
}; 
int len = 48; 
//open the socket 
int s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); 
//don't fill header 
int optval = 1; 
setsockopt(s, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval)); 
//destination addr 
struct sockaddr_in addr; 
memset(&addr, 0, sizeof(addr)); 
addr.sin_family = AF_INET; 
addr.sin_addr.s_addr = inet_addr("192.168.200.135"); 
//send 
sendto(s, data, len, 0, (struct sockaddr*)&addr, sizeof(addr)); 
+0

라우터에서 * (i) * [IP 전달 사용] (http://linuxpoison.blogspot.de/2008/01/how-to-enable-ip-forwarding.html)을 확인 했습니까? * (ii) * 프로그램은 루트 권한으로 실행됩니다 (원시 소켓에 필요). – mavam

+0

해당 패킷의 wireshark 출력을 추가 할 수 있습니까? '헤더 길이'로 설명하는 '50'은 '데이터 오프셋'입니다. http://tools.ietf.org/html/rfc793 확인 - 마지막으로 TCP는 연결 지향적입니다. 대신 UDP를 사용하지 않으시겠습니까? –

+0

@MatthiasVallentin (i) IP 포워딩이 가능합니다. 그렇지 않으면 B에서 A로 ssh 및 ping을 할 수 없습니다 (내 라우터는 CISCO WRVS4400N 임). (ii) root로 프로그램을 실행합니다. 그렇지 않으면 socket()의 반환 값은 -1이됩니다. – Haoshu

답변

0
  1. 라우터 192.168.1.1을 기본 라우터해야합니다. 컴퓨터 A에서 구성을 확인하십시오.
0

플래그가 누락되어 TCP 헤더가 잘못되었습니다. 테스트를 위해서는 적어도 SYN 플래그를 설정해야합니다. 헤더로 수정되지 않은 다른 사항이있을 수 있습니다.

라우터가 실제로 TCP 헤더를 검사하고 있다면 패킷을 버리게됩니다. 라우터가 실제로 라우팅되지 않고 패킷 전달을 위해 NAT를 사용하거나 포트 또는 연결 상태를 확인하는 방화벽이있는 경우 TCP 헤더를 검사합니다.

관련 문제