2014-10-23 4 views
7

저는 C/C++ 네트워킹 프로젝트에서 IPv4 및 IPv6 네트워킹 스택을 모두 사용할 수 있어야합니다. 프로젝트는 Linux에서만 작동합니다. 그래서 IP 주소를 저장하고 프로토콜 제품군을 구분하는 효율적인 방법을 찾으려고했습니다. 첫 번째 방법은 연합 갖도록 하였다 :효율적인 방법으로 IPv4/IPv6 주소를 저장합니다.

struct ip_addr { 
    uint8_t fam; // socket family type 
    union { 
     struct in_addr ipv4_sin_addr; 
     struct in6_addr ipv6_sin_addr; 
    }addr; 
}; 

번째 방법은 typedef std::vector<unsigned char> IPAddressNumber을 정의하고, 벡터의 바이트 수 후의 차이를 확인 하였다.

제 3 수법은 GCC에서

/또는 uint128_t __int128_t int128_t을 사용하는 것이었다.

이 지난 경우, 나는, 이러한 유형이 지원되는 GCC의 버전을 알고 싶습니다하는 플랫폼 (특히 IA-32/IA-64)도 알려진 버그가있는 경우. 또한 위의 솔루션 중 가장 편리한 솔루션은 무엇입니까?

+1

IPv6 주소에 'int128_t'가 필요하거나 적합하지 않은 것인지 잘 모르겠습니다. Posix는 API에 다른 유형을 제공합니다. GCC의 경우 최신 버전 (2014 년 10 월 GCC 4.9.1)을 사용하고 가능한 경우 C++ 11을 사용하십시오. –

+2

IPv6 주소를 처리하기 위해 [struct sockaddr_in6'] (http://man7.org/linux/man-pages/man7/ipv6.7.html) 구조를 사용하는 것이 좋습니다. –

+0

IP 주소를 실제 숫자로 사용하는 경우가 거의 없습니다 (네트워크 바이트 순서로 제공해야 함). 다시 한번 : IPv6 주소를 표현하기 위해'uint128_t'를 사용하는 것은 아마 ** 매우 나쁜 생각입니다 **! –

답변

3

this thread__int128_t__uint128_t은 버전 4.2 주변에 도입되었습니다. 그리고 GCC의 문서 __int128과 그 부호없는 대응 물 unsigned __int128GCC 4.6.4부터 지원됩니다.

변환 할 수없는 128 비트 정수는 확실히 이 아니며 IPv6 주소로 저장하고 작업하기에 적합한 유형이이 아닙니다. 주석에서 언급했듯이 sockaddr_in6과 같은 특수한 데이터 구조가 있습니다.

+0

글쎄,이 128 비트 정수 지원에 대한 답변,하지만 그 IPv6 주소의 표현을위한 올바른 데이터 형식이 아닌가 두렵다 : -/... –

+0

@ πάνταῥεῖ 나는 대답을 업데이 트했습니다. 보다 나은? – Columbo

+0

나는 조언을 받아서 지금 내 자신의 답을 달았다. 그러나 Y 문제를 지적하면 대답이 향상됩니다. –

9

1st answer에서 설명한대로 128 비트 정수 지원은 GCC 4.6.4부터 사용할 수 있습니다.

귀하의 문제는 128 비트 정수를 지원하지 않지만 어떻게 제대로 IPv6 주소를 나타냅니다.
이에 대한 정답은 socket API에서 사용할 수있는 struct 정의를 사용하는 것입니다.

IPv6 스택의 다양한 운영 체제 구현에 사용할 수 있고 표준화되어 있습니다.
또한 효율에 대해 걱정할 필요가 없습니다. Alignment 패킹은 올바르게 작동 할 것이고 실제 표현의 endianess vs network byte order 문제에 신경 쓸 필요가 없습니다. 편집에 관해서는


:

당신은 바퀴를 재발견 할 필요가 없습니다!AF_xxx 제품군 유형을 올바르게 고려하면 이미 적절한 struct 정의가 사용 가능합니다.자세한 설명을 위해

확인이 자원 :

  • sys/socket.h - main sockets header
  • 우리는 sa_family을 기반으로 IpAddr 중 하나 sockaddr* 포인터를 기반으로 IPv4 또는 IPv6 주소를 캡슐화 불투명 sockaddr_in*sockaddr_in6* 포인터를 사용하여 생산 클래스 및 reinterpret_cast<>이 구조체의 멤버.

    +0

    실제로 당신이 언급 한 것과 비슷한 표현을 사용하는 오픈 소스 프로젝트 (chromium)를 보았습니다.이 구조체는 SockaddrStorage [1]라는 구조체와이 구조체와 함께 작동하는 IPEndPoint라는 클래스를 사용합니다. 이 구조체의 문제점은 포트를 가지고 있거나 ip를 저장하는 것뿐만 아니라 소켓 (예 : bind, connect calls)을 만들 때 유용하다는 것입니다. [1] http://goo.gl/hSyW8o – evelina

    +0

    IP를 문자열 표현 (예 : 깃발 또는 환경 변수)에서 변환 한 후 저장하는 내부 방법이 필요합니다. inet_ntop/inet_pton과 같은 호출에 더 편리하기 때문에 struct ip_addr을 사용하면 더 유용합니다. sa_data 필드가 IPv6 주소를 저장할 정도로 크기가 커서 sockaddr을 단독으로 사용하거나 포인터로 사용할 수 없습니다 . – evelina

    +0

    @evelina _ "IP를 문자열 표현 (즉, 플래그 또는 환경 변수에서 변환 한 후)에 저장하는 내부 방법이 필요합니다."_ 글쎄, 나는 이해하지 못한다. _능률_. 위에서 언급 한 구조는 IP 프로토콜 종속 유형을 잘 나타냅니다. –

    관련 문제