2012-09-10 2 views
2

네트워크 스택에서 IP 패킷을 스니핑하기위한 다음 코드 샘플이있는 .NET의 네트워크 프로그래밍이라는 책이 있습니다. 그래서 문체 규칙의 부족을 용서하시기 바랍니다 책에서 코드 샘플 WORD-FOR-WORD를 복사 한 등.NET에서 네트워크 패킷 스니핑 사용 권한 예외

List<string> packets = new List<string>(); 

public void Run() 
{ 
    int len_receive_buf = 4096; 
    int len_send_buf = 4096; 
    byte[] receive_buf = new byte[len_receive_buf]; 
    byte[] send_buf = new byte[len_send_buf]; 
    int cout_receive_bytes; 
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); 
    socket.Blocking = false; 
    IPHostEntry IPHost = Dns.GetHostByName(Dns.GetHostName()); 
    socket.Bind(new IPEndPoint(IPAddress.Parse(IPHost.AddressList[0].ToString()), 0)); 
    socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1); 
    byte[] IN = new byte[4] { 1, 0, 0, 0 }; 
    byte[] OUT = new byte[4]; 
    int SIO_RCVALL = unchecked((int)0x98000001); 
    int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT); 
    while(true) 
    { 
     IAsyncResult ar = socket.BeginReceive(receive_buf, 0, len_receive_buf, SocketFlags.None, null, this); 
     cout_receive_bytes = socket.EndReceive(ar); 
     Receive(receive_buf, cout_receive_bytes); 
    } 
} 

public void Receive(byte[] buf, int len) 
{ 
    if(buf[9] == 6) 
    { 
     packets.Add(Encoding.ASCII.GetString(buf).Replace("\0", " ")); 
    } 
} 

첫 번째 나는 (심지어 비스타가 존재하기 전에)이 몇 년 전 테스트 시간과 내가 사용했던 컴퓨터는 IPv4에서 실행되는 NIC가있는 32 비트 Windows XP Proferssional 플랫폼이었습니다.

이제 IPv6를 실행하는 NIC가있는 64 비트 Windows 7 플랫폼에서 테스트하려고하지만 작동하지 않습니다. 나는 이것이 IPv6과 관련이 있다고 가정하고있다. 누구든지이 문제를 어떻게 효과적으로 해결할 수 있을지 제안 할 수 있습니까?

편집 :이

enter image description here

+3

어떻게 작동하지 않습니까? –

+2

'IPAddress.Parse (IPHost.AddressList [0] .ToString()) '과 같은 보석을 포함하는 코드의 저자에 대해 진지하게 질문 할 것입니다. 단지'IPHost.AddressList [0]'뿐 아니라 왜? –

+0

@Damien_The_Unbeliever 나는 꽤 동의한다! – series0ne

답변

6

헤더 IPv4IPv6 사이에 유의 한 차이가 있습니다 ... 제가 실행하려고하면 내가 얻을 예외입니다.

그래서의 검사 : 패킷이 IPv4의 TCP는 IPv6 패킷의 소스 주소 필드의 일부를 쿼리입니다 여부를 확인

if(buf[9] == 6) 

. IPv6의 경우 오프셋 6 *에있는 "다음 헤더"를 확인해야합니다. 물론, 지금 당신은 또한 6 오프셋 확인하거나 예외 메시지에 대해 9


을 상쇄 할 것인지 IP 버전을 확인하기 위해 먼저 알고해야합니다, 당신이, 관리자 권한으로 실행하지 않을 가능성이 높습니다하는 당신은 (여전히 적용되는 기본 문서 만) raw sockets에서 수신하도록 할 필요가 :

SOCK_RAW가 관리자 권한이 필요 타입의 소켓을 사용합니다. 원시 소켓을 사용하는 Winsock 응용 프로그램을 실행하는 사용자는 로컬 컴퓨터에서 Administrators 그룹의 구성원이어야합니다. 그렇지 않으면 원시 소켓 호출이 오류 코드 WSAEACCES과 함께 실패합니다. Windows Vista 이상에서는 원시 소켓에 대한 액세스가 소켓 생성시 적용됩니다. 이전 버전의 Windows에서는 원시 소켓에 대한 액세스가 다른 소켓 작업 중에 적용됩니다.


(*) 물론, 당신이 TCP 패킷의 것을 발견하기 전에 여러 IPv6의 헤더를 통해 일이있을 수 있습니다.

+0

안녕하세요, 게시 주셔서 감사합니다. 코드는 분명히 많이 업데이트해야합니다 ... 예제 예외에 대한 마지막 편집을 참조하십시오. – series0ne

+0

마지막 수정 해 주셔서 감사합니다. 높은 권한으로 실행하면 올바른 IP 주소가 주어집니다. - 답변 가능 – series0ne