Networking

IPv6

Internet Protocol version 6 - The latest version of the Internet Protocol using 128-bit addresses, designed to replace IPv4 and provide virtually unlimited address space for internet-connected devices.

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

  1. Support both IPv4 and IPv6 (dual-stack)
  2. Use bracket notation for IPv6 in URLs
  3. Validate IPv6 addresses properly
  4. Test on IPv6-only networks
  5. Use libraries for IP address handling

For Network Configuration

  1. Enable IPv6 on infrastructure
  2. Configure firewalls for IPv6
  3. Implement Router Advertisement security
  4. Plan IPv6 addressing scheme
  5. Monitor IPv6 connectivity

For Security

  1. Apply firewall rules to IPv6
  2. Filter ICMPv6 appropriately
  3. Secure Router Advertisements
  4. Monitor for IPv6 tunnels
  5. Use IPsec when needed

Learn More

Create a free Account to fix CORS Errors in Production

Say goodbye to CORS errors and get back to building great web applications. It's free!

CORSPROXY Dashboard

Related Terms

More in Networking

Related guides

Back to Glossary