2016-07-16 2 views
2

IPv6 확장 헤더를 검사하고 수정해야합니다. 그래서 원시 소켓을 설정하여 로컬 주소의 모든 IP 패킷을 수신합니다.IPv6 패킷 헤더 조작

package main 

import (
    "log" 
    "net" 
) 

func main() { 
    c, err := net.ListenIP("ip6:tcp", &net.IPAddr{ 
     IP: net.IPv6loopback, 
     Zone: "", 
    }) 
    if err != nil { 
     panic(err) 
    } 

    buf := make([]byte, 1024) 
    for { 
     numRead, ipaddr, err := c.ReadFromIP(buf) 
     log.Print(numRead, ipaddr, err) 
     log.Printf("% X\n", buf[:numRead]) 
    } 
} 

나는 연결의 모든 Read*() 방법을 시도했지만 그들은 단지 헤더없이 페이로드를 반환처럼 보인다. 내 질문 : 어떻게 패킷의 IPv6 헤더에 액세스 할 수 있습니까?

+0

한 가지의 IPv6 확장 헤더는 거의 사용되지 않았는지, 그리고, 유감스럽게도 경로에있는 많은 ISP는 공격에 사용될 수 있기 때문에 확장 헤더를 차단하거나 제거합니다. –

답변

3

IPv6이있는 Raw 소켓은 IPv4와 다릅니다. 귀하의 사례와 관련된 것은 RFC 3542입니다. 참고

IPv4의 원시 소켓의 또 다른 차이는 완전한 패킷 (즉, 확장 헤더와 IPv6 패킷)는 IPv6 원시 소켓 API를 사용하여 전송 또는 수신 할 수없는 이다. 대신에 부가적인 데이터 객체가 6 장에서 설명한대로 확장 헤더와 호핑 정보를 전송하는 데 사용됩니다. 응용 프로그램이 완전한 IPv6 패킷에 액세스해야한다면 데이터 링크 인터페이스 BPF 또는 DLPI와 같은 다른 기술이 필요합니다. 사용하십시오.


당신은 당신의 자신에이를 확인할 수 있습니다. 모든 패킷 내 상자에 프로그램을 실행 (및 strace'ing)에 의해 내가 얻을 :

recvfrom(3, "\x45\x00\x00\x3c\x6a\x7d... 
       ^^ 

는 IP 버전 = 4, IHL = 5 (20 바이트)를 의미한다.

내가 IPv6를 (즉, 원래의 코드)와 같은 일을하려고 할 때, 나는 다른 무언가를 할 때마다 얻을이에 (이 경우

recvfrom(3, "\xc6\x22\x00\x50\x4d 

커널이 TCP와 직접 시작하는 물건을 반환 할 때마다 포트가 50722 인 경우, 즉 0xC622).

또 다른 흥미로운 부분

sources에 주목해야한다 :

switch sa := sa.(type) { 
case *syscall.SockaddrInet4: 
    addr = &IPAddr{IP: sa.Addr[0:]} 
    n = stripIPv4Header(n, b) 
case *syscall.SockaddrInet6: 
    addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))} 
} 

헤더는 IPv6를 수동으로 IPv4의에 대한 아니라 제거되어 IPv6의 제거 아무것도 없다.


추가 정보를 반환하는 메커니즘이 있습니다 (단, 전체 패킷은 아닙니다). 예를 들어, IPV6_RECVPKTINFO 소켓 옵션을 사용하면에 액세스 할 수 있습니다 : 라우팅 헤더 옵션이 존재

struct in6_pktinfo { 
    struct in6_addr ipi6_addr; /* src/dst IPv6 address */ 
    unsigned int ipi6_ifindex; /* send/recv interface index */ 
}; 

비슷한 옵션,주의 할 등 홉 제한

+0

답변 해 주셔서 감사합니다. 나는 이미 헤더가 제거되었지만 그 이유를 알지 못했던 부분에서 주목했다. 그래서 나는'net' 패키지로 할 수없는 것 같아요?! – fl0cke

+0

@ fl0cke 그물 패키지가 충분하지 않다고 생각합니다. 리눅스 관련 ['PF_PACKET'] (http://man7.org/linux/man-pages/man7/packet.7.html)이나 BPF (많은 Unixes에서 사용 가능)로 벗어날 수 있습니다. – cnicutar

관련 문제