static void __fastcall ssh_address_valid_check(SshAddressAddContext ctx) { SshIpAddrStruct ip; NTSTATUS status; if (ctx->row.Address.si_family == AF_INET) SSH_IP4_DECODE(&ip, &ctx->row.Address.Ipv4.sin_addr.S_un.S_un_b); else if (ctx->row.Address.si_family == AF_INET6) SSH_IP6_DECODE(&ip, &ctx->row.Address.Ipv6.sin6_addr.u.Byte); status = GetUnicastIpAddressEntry(&ctx->row); if (status == STATUS_SUCCESS) { switch (ctx->row.DadState) { case IpDadStateTentative: if (ctx->ttl) { SSH_DEBUG(SSH_D_NICETOKNOW, ("IP address[%@], DAD state = TENTATIVE " "(retry count=%u)", ssh_ipaddr_render, &ip, ctx->ttl)); /* DAD is still pending and this address is still tentative. Let's check it again after 100 milliseconds. */ ctx->ttl--; ssh_kernel_timeout_register(0, 100000, ssh_address_valid_timeout, ctx); return; } break; case IpDadStatePreferred: SSH_DEBUG(SSH_D_NICETOKNOW, ("Address change: IP address[%@] added", ssh_ipaddr_render, &ip)); SSH_IP_REFRESH_REQUEST(ctx->interceptor); break; case IpDadStateInvalid: case IpDadStateDuplicate: case IpDadStateDeprecated: default: SSH_DEBUG(SSH_D_NICETOKNOW, ("IP address[%@], DAD state=%u " "(address addition failed)", ssh_ipaddr_render, &ip, ctx->row.DadState, ctx->ttl)); break; } } /* done */ InterlockedDecrement(&ctx->interceptor->ref_count); ssh_free(ctx); }
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"); } }