Unspecified or 0:0:0:0 or * address - represents any address, but should not be present on outgoing packets. If you bind a listening socket to 0.0.0.0, you're telling the OS to accept connections on any ip address that the host has network adapters bound to. e.g. if your host had two network adapters with two different ip addresses. You can bind a socket to either one and it will accept connections only on that adapter. Or you can bind a socket to 0.0.0.0 (INADDR_ANY in WinSock) and it will bind to both adapters.
Private address - used within organization, range from 192.168.0.0 to 192.168.255.255 and 172.16.0.0 to 172.16.255.255
Public address - can be static or dynamic(per internet session). Static IP's are used sometime for gaming or hosting website etc.
IPV6 - IPV4 is 4 part address with each part size is of 8 bits, so totally 32 bits. It allows 4,29,49,67,296 or 2^32 addresses. But IPV6 is 8 part address with each part size is of 16 bits, so totally 128 bits.
Sample code to figure out whether IP address is 32 or 128 bits
string input = "your IP address goes here";
IPAddress address;
if (IPAddress.TryParse(input, out address))
{
switch (address.AddressFamily)
{
case System.Net.Sockets.AddressFamily.InterNetwork:
// we have IPv4
break;
case System.Net.Sockets.AddressFamily.InterNetworkV6:
// we have IPv6
break;
default:
// umm... yeah... I'm going to need to take your red packet and...
break;
}
}