void NetPlatform_addAddress(const char* interfaceName, char* addrBytes, int prefixLen, int addrFam, struct Log* logger, struct Except* eh) { unsigned long ifIndex; WinFail_check(eh, GetAdapterIndex(interfaceName, &ifIndex)); MIB_UNICASTIPADDRESS_ROW ipRow; InitializeUnicastIpAddressEntry(&ipRow); ipRow.InterfaceIndex = ifIndex; ipRow.Address.si_family = addrFamily; if (addrFam == Socket_AF_INET6) { Bits_memcpy(&ipRow.Address.Ipv6.sin6_addr, addr, 16); } else if (addrFam == Socket_AF_INET) { Bits_memcpy(&ipRow.Address.Ipv4.sin_addr, addr, 4); } else { Assert_always(0); } ipRow.OnLinkPrefixLength = prefixLen; WinFail_check(eh, CreateUnicastIpAddressEntry(&ipRow)); }
void c_tun_device_windows::set_ipv6_address (const std::array<uint8_t, 16> &binary_address, int prefixLen) { _fact("Setting IPv6 address, prefixLen="<<prefixLen); std::wstring human_name = get_human_name(m_guid); NET_LUID luid = get_luid(human_name); _fact("Setting address on human_name " << to_string(human_name));// << " luid=" << to_string(luid)); // remove old address MIB_UNICASTIPADDRESS_TABLE *table = nullptr; NETIOAPI_API status = GetUnicastIpAddressTable(AF_INET6, &table); if (status != NO_ERROR) throw std::runtime_error("GetUnicastIpAddressTable error, code"); for (int i = 0; i < static_cast<int>(table->NumEntries); ++i) { _info("Removing old addresses, i="<<i); if (table->Table[i].InterfaceLuid.Value == luid.Value) { _info("Removing old addresses, entry i="<<i<<" - will remove"); if (DeleteUnicastIpAddressEntry(&table->Table[i]) != NO_ERROR) { FreeMibTable(table); throw std::runtime_error("DeleteUnicastIpAddressEntry error"); } } } FreeMibTable(table); // set new address _fact("Setting new IP address"); MIB_UNICASTIPADDRESS_ROW iprow; std::memset(&iprow, 0, sizeof(iprow)); iprow.PrefixOrigin = IpPrefixOriginUnchanged; iprow.SuffixOrigin = IpSuffixOriginUnchanged; iprow.ValidLifetime = 0xFFFFFFFF; iprow.PreferredLifetime = 0xFFFFFFFF; iprow.OnLinkPrefixLength = 0xFF; iprow.InterfaceLuid = luid; iprow.Address.si_family = AF_INET6; std::memcpy(&iprow.Address.Ipv6.sin6_addr, binary_address.data(), binary_address.size()); iprow.OnLinkPrefixLength = prefixLen; _fact("Creating unicast IP"); status = CreateUnicastIpAddressEntry(&iprow); if (status != NO_ERROR) throw std::runtime_error("CreateUnicastIpAddressEntry error"); _goal("Created unicast IP, status=" << status); }
VOID AddressDemo( VOID ) { NETIO_STATUS Status; PMIB_UNICASTIPADDRESS_TABLE UnicastTable = NULL; MIB_UNICASTIPADDRESS_ROW Row; ULONG i; IN6_ADDR Ipv6Address = {0xfe,0x3f,0,0,0,0,0,0,0,0,0,0,0,0,0x20,0x00}; HANDLE Handle; NET_IFINDEX InterfaceIndex = 0; // // Retrieve all the IP addresses. // Status = GetUnicastIpAddressTable( AF_UNSPEC, &UnicastTable); if (!WIN_SUCCESS(Status)) { printf( "GetUnicastAddressTable Failed. Error %d\n", Status); } else { printf( "GetUnicastAddressTable Succeeded.\n"); printf( "Total Number of all IP Address Entries: %d.\n", UnicastTable->NumEntries); for (i = 0; i < UnicastTable->NumEntries; i++) { printf("Address %2d: ", i); PrintIpAddress(&UnicastTable->Table[i].Address); printf("\n"); } FreeMibTable(UnicastTable); printf("\n\n"); } // // Retrieve IPv6 Only Addresses. // Status = GetUnicastIpAddressTable( AF_INET6, &UnicastTable); if (!WIN_SUCCESS(Status)) { printf( "GetUnicastAddressTable Failed. Error %d\n", Status); } else { printf( "GetUnicastAddressTable Succeeded.\n"); printf( "Total Number of IPv6 Address Entries: %d.\n", UnicastTable->NumEntries); for (i = 0; i < UnicastTable->NumEntries; i++) { printf("Address %2d: ", i); PrintIpAddress(&UnicastTable->Table[i].Address); printf("\n"); } InterfaceIndex = UnicastTable->Table[i - 1].InterfaceIndex; FreeMibTable(UnicastTable); } Status = NotifyUnicastIpAddressChange( AF_UNSPEC, //(PUNICAST_IPADDRESS_CHANGE_CALLBACK)AddressCallbackDemo, &AddressCallbackDemo, NULL, FALSE, &Handle); if (!WIN_SUCCESS(Status)) { printf( "\nRegister address change failed. Error %d\n", Status); } else { printf( "\nRegister address change succeeded.\n"); } InitializeUnicastIpAddressEntry(&Row); Row.Address.si_family = AF_INET6; INETADDR_SET_ADDRESS((PSOCKADDR)&Row.Address, (PUCHAR)&Ipv6Address); Row.InterfaceIndex = InterfaceIndex; Status = CreateUnicastIpAddressEntry(&Row); if (!WIN_SUCCESS(Status)) { printf("Create IPv6 unicast address entry failed. Error %d\n", Status); } else { printf("Create IPv6 unicast address entry succeeded.\n"); } Status = GetUnicastIpAddressEntry(&Row); if (!WIN_SUCCESS(Status)) { printf("Get IPv6 unicast address failed. Error %d\n", Status); } else { printf("Get IPv6 unicast address entry succeeded.\n"); } Row.PreferredLifetime = 500000; Status = SetUnicastIpAddressEntry(&Row); if (!WIN_SUCCESS(Status)) { printf("Set IPv6 unicast address entry failed. Error %d\n", Status); } else { printf("Set IPv6 unicast address entry succeeded.\n"); } Status = DeleteUnicastIpAddressEntry(&Row); if (!WIN_SUCCESS(Status)) { printf("Delete Ipv6 Unicast Address Failed. Error %d\n", Status); } else { printf("Delete Ipv6 Unicast Address Succeeded.\n"); } Sleep(2000); Status = CancelMibChangeNotify2(Handle); if (!WIN_SUCCESS(Status)) { printf( "Deregister address change failed. Error %d\n\n", Status); } else { printf( "Deregister address change succeeded.\n\n"); } }