What is IPv6?
IPv6 (Internet Protocol version 6) is the most recent version of the Internet Protocol, designed to replace IPv4. It uses 128-bit addresses written in hexadecimal notation separated by colons, providing approximately 340 undecillion (3.4 × 10³⁸) unique addresses—enough to assign an IP address to every atom on Earth’s surface and still have plenty left over.
IPv6 Address Structure
Address Format
Full IPv6 address:
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Compressed notation (omit leading zeros):
2001:db8:85a3:0:0:8a2e:370:7334
Compressed notation (collapse consecutive zeros):
2001:db8:85a3::8a2e:370:7334
Loopback:
::1 (equivalent to 127.0.0.1 in IPv4)
All zeros:
:: (equivalent to 0.0.0.0 in IPv4)
128 bits total = 8 groups of 16 bits
Each group: 0-FFFF (hexadecimal)
Total addresses: 2^128 = 340,282,366,920,938,463,463,374,607,431,768,211,456
Address Types
interface IPv6AddressTypes {
unicast: {
global: '2000::/3'; // Global unicast (internet)
linkLocal: 'fe80::/10'; // Local network only
uniqueLocal: 'fc00::/7'; // Private addresses
loopback: '::1/128'; // Localhost
};
multicast: {
prefix: 'ff00::/8'; // Multicast addresses
allNodes: 'ff02::1'; // All nodes on local segment
allRouters: 'ff02::2'; // All routers on local segment
};
anycast: {
description: 'Delivered to nearest node in group';
example: '2001:db8::1';
};
}
IPv6 vs IPv4
Key Differences
interface ProtocolComparison {
ipv6: {
addressSize: 128; // bits
format: '2001:0db8::1';
totalAddresses: '340 undecillion';
header: '40 bytes (fixed)';
security: 'Built-in IPsec support';
configuration: 'Auto (SLAAC)';
fragmentation: 'End nodes only';
broadcast: 'None (uses multicast)';
checksum: 'None (handled by layers above/below)';
};
ipv4: {
addressSize: 32; // bits
format: '192.0.2.1';
totalAddresses: '4.3 billion';
header: '20-60 bytes (variable)';
security: 'Optional (IPsec)';
configuration: 'DHCP or manual';
fragmentation: 'Routers and endpoints';
broadcast: 'Yes';
checksum: 'Header checksum required';
};
}
Working with IPv6
Parsing and Validation
class IPv6Validator {
// Validate IPv6 address format
isValid(address: string): boolean {
// Remove brackets if present
address = address.replace(/^\[|\]$/g, '');
// Check for double colon (can only appear once)
const doubleColonCount = (address.match(/::/g) || []).length;
if (doubleColonCount > 1) return false;
// Split by colons
const groups = address.split(':');
// Valid IPv6 has 3-8 groups (8 without ::, less with ::)
if (groups.length > 8 || groups.length < 3) return false;
// Validate each group
for (const group of groups) {
if (group === '') continue; // Empty groups from ::
// Check if valid hex (0-FFFF)
if (!/^[0-9a-fA-F]{1,4}$/.test(group)) return false;
}
return true;
}
// Expand compressed IPv6 address
expand(address: string): string {
address = address.replace(/^\[|\]$/g, '');
// Handle :: expansion
if (address.includes('::')) {
const sides = address.split('::');
const leftGroups = sides[0] ? sides[0].split(':') : [];
const rightGroups = sides[1] ? sides[1].split(':') : [];
const missingGroups = 8 - leftGroups.length - rightGroups.length;
const middleGroups = Array(missingGroups).fill('0000');
const allGroups = [...leftGroups, ...middleGroups, ...rightGroups];
address = allGroups.join(':');
}
// Pad each group to 4 digits
return address
.split(':')
.map(group => group.padStart(4, '0'))
.join(':');
}
// Compress IPv6 address
compress(address: string): string {
const expanded = this.expand(address);
const groups = expanded.split(':');
// Find longest sequence of zeros
let longestZeroStart = -1;
let longestZeroLength = 0;
let currentZeroStart = -1;
let currentZeroLength = 0;
groups.forEach((group, i) => {
if (group === '0000') {
if (currentZeroStart === -1) {
currentZeroStart = i;
currentZeroLength = 1;
} else {
currentZeroLength++;
}
if (currentZeroLength > longestZeroLength) {
longestZeroStart = currentZeroStart;
longestZeroLength = currentZeroLength;
}
} else {
currentZeroStart = -1;
currentZeroLength = 0;
}
});
// Replace longest zero sequence with ::
if (longestZeroLength > 1) {
groups.splice(longestZeroStart, longestZeroLength, '');
// Add empty string for :: notation
if (longestZeroStart === 0 || longestZeroStart + longestZeroLength === 8) {
groups.splice(longestZeroStart, 0, '');
}
}
// Remove leading zeros from each group
return groups
.map(group => group.replace(/^0+/, '') || '0')
.join(':')
.replace(/:{3,}/, '::'); // Ensure :: notation
}
}
// Usage
const validator = new IPv6Validator();
console.log(validator.isValid('2001:db8::1')); // true
console.log(validator.expand('2001:db8::1')); // 2001:0db8:0000:0000:0000:0000:0000:0001
console.log(validator.compress('2001:0db8:0000:0000:0000:0000:0000:0001')); // 2001:db8::1
IPv6 in URLs
URL Format
// IPv6 addresses in URLs must be bracketed
const urls = {
http: 'http://[2001:db8::1]/',
https: 'https://[2001:db8::1]:8443/',
withPath: 'https://[2001:db8::1]/api/data',
withPort: 'http://[2001:db8::1]:3000/app'
};
// Parsing IPv6 URLs
class IPv6URLParser {
parse(urlString: string) {
const url = new URL(urlString);
// Extract IPv6 address (remove brackets)
const hostname = url.hostname.replace(/^\[|\]$/g, '');
return {
protocol: url.protocol,
hostname,
port: url.port || (url.protocol === 'https:' ? '443' : '80'),
pathname: url.pathname,
isIPv6: this.isIPv6(hostname)
};
}
private isIPv6(hostname: string): boolean {
return hostname.includes(':');
}
}
// Usage
const parser = new IPv6URLParser();
const parsed = parser.parse('https://[2001:db8::1]:8443/api/data');
console.log(parsed);
IPv6 with Proxies
Configuring IPv6 Proxies
async function useIPv6Proxy() {
// Using CorsProxy with IPv6 preference
const response = await fetch(
'https://corsproxy.io/?url=https://api.example.com/data',
{
headers: {
'x-cors-api-key': process.env.CORS_API_KEY!,
'x-cors-ip-version': 'ipv6', // Request IPv6 if available
'User-Agent': 'Mozilla/5.0...'
}
}
);
return response.json();
}
// Check current IP version
async function checkIPVersion() {
// Check IPv4
try {
const ipv4Response = await fetch('https://api.ipify.org?format=json');
const { ip: ipv4 } = await ipv4Response.json();
console.log('IPv4:', ipv4);
} catch (error) {
console.log('IPv4 not available');
}
// Check IPv6
try {
const ipv6Response = await fetch('https://api6.ipify.org?format=json');
const { ip: ipv6 } = await ipv6Response.json();
console.log('IPv6:', ipv6);
} catch (error) {
console.log('IPv6 not available');
}
}
Dual-Stack Support
IPv4 and IPv6 Compatibility
class DualStackClient {
async fetch(hostname: string, preferIPv6: boolean = false) {
try {
if (preferIPv6) {
// Try IPv6 first
return await this.fetchIPv6(hostname);
}
} catch (error) {
console.log('IPv6 failed, falling back to IPv4');
}
// Fall back to IPv4
return this.fetchIPv4(hostname);
}
private async fetchIPv6(hostname: string) {
// Force IPv6 by using IPv6 address or domain with AAAA record
const response = await fetch(`https://[${hostname}]/`);
return response;
}
private async fetchIPv4(hostname: string) {
const response = await fetch(`https://${hostname}/`);
return response;
}
async resolveIPv6(hostname: string): Promise<string | null> {
try {
// DNS lookup for AAAA record
const response = await fetch(
`https://dns.google/resolve?name=${hostname}&type=AAAA`
);
const data = await response.json();
if (data.Answer && data.Answer.length > 0) {
return data.Answer[0].data;
}
} catch (error) {
console.error('IPv6 resolution failed:', error);
}
return null;
}
}
// Usage
const client = new DualStackClient();
// Try IPv6 first, fall back to IPv4
const response = await client.fetch('example.com', true);
// Resolve IPv6 address
const ipv6 = await client.resolveIPv6('google.com');
console.log('IPv6 address:', ipv6);
IPv6 Subnetting
Subnet Allocation
interface IPv6Subnet {
prefix: '2001:db8::/32';
size: 96; // bits for host addresses
networks: '2^96 possible hosts';
}
// Common IPv6 prefix lengths
const commonPrefixes = {
'/48': 'Typical site allocation',
'/56': 'Small site or home',
'/64': 'Single subnet/network',
'/128': 'Single host (like /32 in IPv4)'
};
// Calculate subnet
function calculateIPv6Subnet(cidr: string) {
const [address, prefixStr] = cidr.split('/');
const prefix = parseInt(prefixStr, 10);
const hostBits = 128 - prefix;
const possibleHosts = BigInt(2) ** BigInt(hostBits);
return {
address,
prefix,
hostBits,
possibleHosts: possibleHosts.toString(),
subnetMask: `ffff:ffff:ffff:ffff:${'0000:'.repeat(Math.max(0, 8 - prefix / 16))}`.slice(0, -1)
};
}
// Usage
console.log(calculateIPv6Subnet('2001:db8::/32'));
// {
// address: '2001:db8::',
// prefix: 32,
// hostBits: 96,
// possibleHosts: '79228162514264337593543950336'
// }
SLAAC (Stateless Address Autoconfiguration)
Automatic IPv6 Configuration
SLAAC Process:
1. Device sends Router Solicitation (RS)
2. Router responds with Router Advertisement (RA)
- Network prefix (e.g., 2001:db8::/64)
- Gateway information
- DNS servers
3. Device generates host part using:
- EUI-64 (from MAC address)
- or Privacy Extensions (random)
4. Device performs Duplicate Address Detection (DAD)
5. Address is configured automatically
Example:
Network Prefix: 2001:db8:1234:5678::/64
MAC Address: 00:1A:2B:3C:4D:5E
EUI-64 Address:
2001:db8:1234:5678:021a:2bff:fe3c:4d5e
Privacy Extension Address:
2001:db8:1234:5678:a5b3:8f21:9c4d:7e12 (random)
IPv6 Security
Security Considerations
interface IPv6Security {
advantages: {
builtInIPsec: 'Mandatory IPsec support';
noBroadcast: 'No broadcast = reduced attack surface';
largeAddressSpace: 'Harder to scan networks';
};
challenges: {
newAttackVectors: 'Router Advertisement spoofing';
complexity: 'More complex configuration';
dualStack: 'Maintaining two protocols';
};
bestPractices: {
filterICMPv6: 'Allow necessary ICMPv6, block rest';
useFirewall: 'IPv6 firewall rules required';
monitorRA: 'Protect against rogue RAs';
disableIfUnused: 'Disable IPv6 if not needed';
};
}
Migration from IPv4 to IPv6
Transition Mechanisms
interface IPv6TransitionMechanisms {
dualStack: {
description: 'Run IPv4 and IPv6 simultaneously';
pros: 'Simple, widely supported';
cons: 'Requires both protocols';
};
tunneling: {
description: 'Encapsulate IPv6 in IPv4 packets';
types: ['6to4', '6in4', 'Teredo', 'ISATAP'];
use: 'IPv6 over IPv4 infrastructure';
};
translation: {
description: 'Convert between IPv4 and IPv6';
protocols: ['NAT64', 'DNS64'];
use: 'IPv6-only to IPv4-only communication';
};
}
IPv6 Address Allocation
Regional Internet Registries
IANA allocates to RIRs:
- ARIN (North America)
- RIPE NCC (Europe, Middle East)
- APNIC (Asia Pacific)
- LACNIC (Latin America, Caribbean)
- AFRINIC (Africa)
RIRs allocate to:
- ISPs: Typically /32 or larger
- Organizations: /48 (65,536 /64 subnets)
- End users: /56 or /64
Practical IPv6 Usage
Common Scenarios
// Detecting IPv6 support
async function hasIPv6Support(): Promise<boolean> {
try {
const response = await fetch('https://api6.ipify.org', {
signal: AbortSignal.timeout(3000)
});
return response.ok;
} catch {
return false;
}
}
// Prefer IPv6 when available
async function smartFetch(url: string) {
const supportsIPv6 = await hasIPv6Support();
if (supportsIPv6) {
console.log('Using IPv6');
// Modern systems will prefer IPv6 automatically
return fetch(url);
}
console.log('Using IPv4');
return fetch(url);
}
Best Practices
For Developers
- Support both IPv4 and IPv6 (dual-stack)
- Use bracket notation for IPv6 in URLs
- Validate IPv6 addresses properly
- Test on IPv6-only networks
- Use libraries for IP address handling
For Network Configuration
- Enable IPv6 on infrastructure
- Configure firewalls for IPv6
- Implement Router Advertisement security
- Plan IPv6 addressing scheme
- Monitor IPv6 connectivity
For Security
- Apply firewall rules to IPv6
- Filter ICMPv6 appropriately
- Secure Router Advertisements
- Monitor for IPv6 tunnels
- Use IPsec when needed