2011-03-29 1 views

답변

7

. 네이티브 128 비트 타입이 없습니까? http://www.mail-archive.com/[email protected]/msg00195.html 따르면

는 :

IPv6 주소는 이들이 이진 형태로있을 때마다 네트워크 바이트 순서 에 representd 것으로 예상된다 (라우터에서 호스트에 에 와이어 등) . 다른 곳에서는 RFC 2553, 섹션 3.2를 참조하십시오. RFC 2553 가입일

:

struct in6_addr { 
    uint8_t s6_addr[16];  /* IPv6 address */ 
}; 

이 데이터 : 새로운 된 in6_addr 구조는 하나의 IPv6 주소를 보유 포함의 결과로 정의된다

3.2 IPv6 주소 구조 구조체는 하나의 128 비트 IPv6 주소를 구성하는 16 개의 8 비트 요소의 배열을 포함합니다. IPv6 주소는 네트워크 바이트 순서로 저장됩니다.

위의 in6_addr 구조는 일반적으로 "struct in_addr"의 BSD 구현과 비슷한 방식으로 원하는 정렬 수준을 강제하는 추가 필드가있는 포함 된 통합으로 구현됩니다. 이들 추가적인 구현 세부 사항은 간략화를 위해 여기서는 생략된다. 다음

예는 다음

struct in6_addr { 
    union { 
     uint8_t _S6_u8[16]; 
     uint32_t _S6_u32[4]; 
     uint64_t _S6_u64[2]; 
    } _S6_un; 
}; 
#define s6_addr _S6_un._S6_u8 
1

경고 : C 프리 프로세서 (예를 들어, CPP) _S6_un._S6_u8와 s6_addr의 모든 인스턴스를 대체하는 경우, 그대로, 만 반드시 적절한 문맥에서 s6_addr의 값을 사용하십시오. 예를 들어 'void * s6_addr();'이 (가) 있기 때문에 함수, 데이터 유형 또는 프로토 타입의 이름을 's6_addr'으로 지정하면 안됩니다. 유효하지 않은 구문 인 'void * _S6_un._S6_u8();'을 생성합니다. 이 코드는 컴파일되지 않습니다

주의 사항 :

struct in6_addr { 
    union { 
     unsigned char _S6_u8[16]; 
     unsigned long _S6_u32[4]; 
     unsigned long long _S6_u64[2]; 
    } _S6_un; 
}; 
#define s6_addr _S6_un._S6_u8 

void *s6_addr(); 

은 그래서 #DEFINE는 인식에 영향을 끼친다.

부작용없이 구현할 수있는 방법이 있습니까?

+0

이것은 모든 #define에 해당합니다. 당신은 항상 부작용에 매우 조심해야합니다. 함수 이름에 형식 이름이 필요하거나 그렇지 않으면 정확한 의도 된 컨텍스트에서 #define을 사용하지 않으면 항상 결과를 알 수 있습니다. – Pyrocater

1

IPv6에서는 ipv6 주소에 대해 네트워크 주문이 필요합니다. hton과 ntoh는 주소를 코드에 저장 한 방식에서 패킷에 저장해야하는 방식 (또는 그 반대)으로 변환하는 것입니다. 따라서 문제는 코드에 저장 한 방법이됩니다.

또한 코드의 IPv6 주소의 정의 방법 더 바이트 단지 배열 이상을 충족하는 것을 허용 할 수

struct in6_addr 
{ 
    union 
    { 
     __u8 u6_addr8[16]; 
     __u16 u6_addr16[8]; 
     __u32 u6_addr32[4]; 
    } in6_u; 
#define s6_addr in6_u.u6_addr8 
#define s6_addr16 in6_u.u6_addr16 
#define s6_addr32 in6_u.u6_addr32 
}; 

IPv6 주소는, 사용자에게,도 8의 16 비트 값으로 표시된다. 코드에 8 개의 16 비트 값으로 저장된 주소가있는 경우 u6_addr16 [] 배열을 사용하여 패킷에 배치 할 때 각 16 비트 값에 hton을 사용해야하고 각 16을 검색 할 때 ntohs를 사용해야합니다 u6_addr16 []에서 비트 값.

이러한 링크는 도움이됩니다 :

0

내가 IPv6를 취급하고 내가 좋아하는 뭔가를 사용 순수한 바이너리 형태로 해결 이 :

// Compile with gcc 
#include <x86intrin.h> 
#include <stdint.h> 
#include <arpa/inet.h> 

// C99 supports __int128! 
typedef unsigned __int128 uint128_t; 

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 

# define htonll(v) __builtin_bswap64((v)) 

    uint128_t hton128(uint128_t val) 
    { 
    // SSE2 is defined if SSSE3. 
# if __SSSE3__ 
    // This routine is 100 cycles faster than the routine below. 
    __m128i m; 
    __m128i mask; 

    m = _mm_loadu_si128((__m128i *)&val); 

    // mask: 0x0f0e0d0c0b0a09080706050403020100 
    mask = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); 

    _mm_store_si128((__m128i *)&val, _mm_shuffle_epi8(m, mask)); 
# else 
    // No SSSE3.. Slowest approach: use pointers to shuffle. 

    uint64_t *p, *q; 

    p = (uint64_t *)&val; 
    q = p + 1; 

    *p = htonll(*p); 
    *q = htonll(*q); 

    { 
     uint64_t t; 

     t = *p; 
     *p = *q; 
     *q = t; 
    } 
# endif 

    return val; 
    } 
#endif