因為IPv6的address一共有128bit,
若要處理的話,
目前long int也只有4 bytes(32bit),
double只有8bytes(64bit)
沒有一個變數可以儲存到128bit,
這個時候就要用到union
直接寫下
/* IPv6 address */
struct in6_addr {
union {
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t 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
};
這個宣告方式,可以讓128bit,
各別的使用8bit在運算。
下面是我寫的一個sub function,
也因為有了這個,
要運算IPv6才會變的比較簡單。
/*
* Filter the IPv6 by prefix to Network ID or Interface ID
*
* @param IPv6_Addr_Src the source for filtering
* @param IPv6_Addr_Dst the result of the filtering process
* @param PrefixLen the prefix of the network
* @param MaskType if the value is NetworkPrefix, network prefix would be reserved
* if the value is InterfaceIdentifier, the interface identifier would be reserved
*/
static void
MaskIPv6 (
struct in6_addr IPv6_Addr_Src,
struct in6_addr *IPv6_Addr_Dst,
int PrefixLen,
enum MaskType Direction
)
{
char *AddrPtr, *IndexAddrPtr;
int FullByteNumber, BitNumber;
char Mask;
int Index;
int CurrentPosition;
//
// The bytes of network id part
//
FullByteNumber = PrefixLen / 8;
//
// The bits of network id part
//
BitNumber = PrefixLen % 8;
//
// filter the bytes of Network ID part
//
for (CurrentPosition = 0; CurrentPosition < FullByteNumber; CurrentPosition++) {
if (Direction == NetworkPrefix) {
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & 0xFF;
} else {
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & 0x00;
}
}
//
// filter the bits of Network ID part and the bits of Interface ID part
//
Mask = 0;
if (BitNumber != 0) {
for (Index = 0; Index < BitNumber; Index++) {
Mask = (Mask << 1) | 1;
}
for (Index = 0; Index < 8 - BitNumber; Index++) {
Mask = Mask << 1;
}
if (Direction == InterfaceIdentifier) {
Mask = ~Mask;
}
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & Mask;
CurrentPosition++;
}
//
// filter the bytes of Interface ID part
//
for (; CurrentPosition < 16; CurrentPosition++) {
if (Direction == NetworkPrefix) {
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & 0x00;
} else {
IPv6_Addr_Src.s6_addr[CurrentPosition] = IPv6_Addr_Src.s6_addr[CurrentPosition] & 0xFF;
}
}
//
// Copy the modified IPv6_Addr_Src context for return
//
memcpy (IPv6_Addr_Dst, &IPv6_Addr_Src, sizeof (IPv6_Addr_Src));
}