Overview
NetBurner release 2.8.0 introduced a fundamental change to IP address handling. The IPADDR type evolved from a simple 32-bit integer to a C++ object capable of representing both IPv4 and IPv6 addresses. This guide covers the migration path and best practices for dual-stack networking.
Key Changes in 2.8.0+
Before (IPv4 only):**
IPADDR = 32-bit
unsigned integer
Used to hold and manipulate IPv4 and IPv6 addresses in dual stack mode.
Definition ipv6_addr.h:41
After (Dual Stack):**
IPADDR = C++ object (32-bit
for IPv4, 128-bit
for IPv6)
IPv6 Address Assignment
Unlike IPv4's typical single-address-per-interface model, IPv6 interfaces inherently support multiple addresses simultaneously. Understanding how these addresses are assigned is crucial for dual-stack development.
Address Assignment Flow
Network Interface Connected
|
v
┌─────────────────────────────────────┐
│ Link-Local Address (fe80::/64) │
│ Derived from MAC address │
│ Always present, non-routable │
└─────────────────┬───────────────────┘
|
v
┌─────────────────────────────────────┐
│ Router Advertisement Received? │
└─────────────────┬───────────────────┘
|
┌───────────────┴───────────────┐
v v
┌─────────┐ ┌─────────┐
│ YES │ │ NO │
└────┬────┘ └────┬────┘
| |
v v
┌─────────────────────┐ ┌─────────────────────┐
│ Auto-Configuration │ │ DHCPv6 or Static │
│ (SLAAC) │ │ Configuration Only │
└──────────┬──────────┘ └─────────────────────┘
|
v
┌──────────────────────────────┐
│ Prefix Address Generated │
│ (Router Prefix + MAC-based) │
└──────────────────────────────┘
Link-Local Addresses
Every IPv6 interface automatically generates a link-local address (fe80::/64 prefix) derived from its MAC address.
Address Generation:**
MAC Address: 00:03:f4:01:23:47
|
v
Link-Local: fe80::203:f4ff:fe01:2347
Characteristics:**
- Non-routable (local network segment only)
- Used for network negotiation and neighbor discovery
- Always present on IPv6-enabled interfaces
- Deterministic (same for a given MAC address)
Router Auto-Configuration (SLAAC)
Routers advertise network prefixes that devices use to auto-configure global IPv6 addresses.
Address Construction:**
┌──────────────────────────────────────────────────────────┐
│ IPv6 Address (128 bits) │
├──────────────────────────────┬───────────────────────────┤
│ Router Prefix (64 bits) │ Host Portion (64 bits) │
│ From Router Advertisement│ From MAC (EUI-64) │
└──────────────────────────────┴───────────────────────────┘
Example:
Router Prefix: 2001:db8:1:2::
MAC-based Suffix: 203:f4ff:fe01:2347
|
v
Full Address: 2001:db8:1:2:203:f4ff:fe01:2347
Multiple Router Scenario:**
Device Interface
|
|-- Router A Prefix > Address A
|-- Router B Prefix > Address B
|-- Router C Prefix > Address C
+-- Link-Local > fe80::...
DHCPv6 Configuration
DHCPv6 servers provide address assignment and network configuration, similar to DHCPv4 but with enhanced capabilities.
DHCPv6 Types:**
DHCPv6 Server
|
┌───────────────┴───────────────┐
v v
┌─────────────────────┐ ┌─────────────────────┐
│ Information-Only │ │ Stateful
DHCP │
├─────────────────────┤ ├─────────────────────┤
│ - DNS servers │ │ - IP address │
│ - NTP servers │ │ - DNS servers │
│ - Domain search │ │ - NTP servers │
│ - Network params │ │ - Other params │
│ │ │ │
│ NO address assigned │ │ Address assigned │
└─────────────────────┘ └─────────────────────┘
DHCP Namespace.
Definition dhcpd.h:39
Automatic DHCPv6 Activation:**
- Router advertisements can signal DHCPv6 server presence
- NetBurner automatically initiates DHCPv6 client when signaled
- Manual DHCPv6 client start available for networks without routers
Static IP Addresses
Manual address assignment remains available when automatic methods are insufficient or undesired.
Complete Address Assignment Hierarchy
IPv6 Interface
|
┌──────────────┼──────────────┐
v v v
┌──────────────┐ ┌───────────┐ ┌──────────────┐
│ Link-Local │ │ SLAAC │ │ DHCPv6 │
│ (Always) │ │(If Router)│ │(If Available)│
└──────────────┘ └───────────┘ └──────────────┘
|
v
┌─────────────────┐
│ Static Config │
│ (Optional) │
└─────────────────┘
IPADDR Class Migration
Storage Considerations
Critical Change:** When compiled for IPv6, IPADDR grows from 32 bits to 128 bits.
IPv4 Mode: IPv6 Mode:
┌──────────┐ ┌──────────────────────────┐
│ 32 bits │ │ 128 bits │
└──────────┘ └──────────────────────────┘
Impact on Persistent Storage:**
Existing applications storing IPADDR in:
- UserParams structures
- File systems
- Flash memory
- Configuration files
Will encounter deserialization issues when upgrading to IPv6-enabled firmware.
Migration Strategy - Storage Key Pattern:**
struct Config {
uint32_t storageKey;
};
const uint32_t CURRENT_KEY = 2;
void LoadConfig(Config& cfg) {
ReadFromFlash(&cfg, sizeof(cfg));
if (cfg.storageKey != CURRENT_KEY) {
InitializeDefaults(cfg);
cfg.storageKey = CURRENT_KEY;
SaveConfig(cfg);
}
}
Null Value Checking
Old IPv4 Pattern (No Longer Valid):**
New Dual-Stack Pattern:**
if (EthernetIP.IsNull()) {
}
Null IP in Function Parameters
Old IPv4 Pattern:**
int GetHostByName(const char *name, IPADDR *pIpaddr, const IPADDR &dns_server, const TickTimeout tout, uint16_t TYPE1=DNS_A, uint16_t TYPE2=extra_dns_t, uint32_t *ttl=NULL)
Get the IP address associated with the specified domain name.
Definition dns.h:184
#define TICKS_PER_SECOND
System clock ticks per second.
Definition constants.h:49
New Dual-Stack Patterns:**
static IPADDR6 NullIP()
Static function to return a null IPADDR6 object.
Note: INADDR_ANY is defined as IPADDR::NullIP() in system headers.
IPADDR Member Functions
The IPADDR class uses object-oriented syntax with member functions accessed via dot notation.
Function Types
|
+-- Member Functions (instance.function())
| |
| +-- Setting values
| +-- Checking values
| +-- Output functions
|
+-- Static Functions (IPADDR::function())
|
+-- Factory methods
+-- Utility functions
Setting IP Address Values
Member Functions (Instance Methods):**
Used to store and manipulate IPv4 addresses in dual stack mode.
Definition nettypes.h:225
void SetFromAscii(const char *cp, bool bembed_v4addresses=true)
Set the IP address value of an IPADDR6 object.
void SetFromIP4(IPADDR4 ip)
Set the IP address value of an IPADDR6 object from an IPADD4 object.
void SetNull()
Set the IP address value of an IPADDR6 object to null.
Definition ipv6_addr.h:320
Static Functions (Class Methods):**
IPADDR serverAddr = IPADDR::AsciiToIp(
"192.168.1.1");
IPADDR ipv6Addr = IPADDR::AsciiToIp(
"2001:db8::8a2e:370:7334");
Reading and Checking IP Address Values
Boolean Checks:**
bool IsLinkLocal() const
Check if the IP address is the link-local address for the interface.
Definition ipv6_addr.h:175
bool IsEmbeddedIPV4() const
An IPADDR6 object can store a IPv4 or IPv6 address. This function returns true if the instance contai...
Definition ipv6_addr.h:66
bool IsMultiCast() const
Check if the IPADDR6 object contains a Multicast IP address the interface.
Definition ipv6_addr.h:164
bool IsNull() const
Check if the IP address is null.
Definition ipv6_addr.h:133
bool IsLoopBack() const
Check if the IP address is the loopback address for the interface.
Definition ipv6_addr.h:151
Address Type Detection:**
Input Address
|
v
┌─────────────┐
│ IsNull()? │<────────────────────┐
└─────┬───────┘ │
| │
NO v │ YES
┌──────────────────┐ │
│ IsLinkLocal()? │ │ Null Address
└─────┬────────────┘ │
| │
NO v │
┌──────────────────┐ │
│ IsEmbeddedIPV4()?│ │
└─────┬────────────┘ │
| │
NO v │
┌──────────────────┐ │
│ IsMultiCast()? │ │
└─────┬────────────┘ │
| │
v │
Full Global │
IPv6 Address │
Multicast MAC Conversion:**
IPADDR mcastAddr = IPADDR::AsciiToIp(
"ff02::1");
}
MACADR McastMac() const
Return the MAC address used for Multicasts for the interface.
Used to store and manipulate MAC addresses.
Definition nettypes.h:69
Output Functions
Console Output:**
IPADDR addr = IPADDR::AsciiToIp(
"192.168.1.100");
addr.printf();
File Descriptor Output:**
int tcpSocket = ;
serverAddr.fdprintf(tcpSocket);
String Buffer Output:**
char buffer[128];
int written = addr.
sprintf(buffer,
sizeof(buffer));
printf("Address: %s (%d chars)\n", buffer, written);
int sprintf(char *cp, int maxl, bool bCompact=true, bool bShowV4Raw=false) const
Print the IP address to the specified buffer.
Output Method Comparison:**
┌───────────────┐
└──────┬────────┘
|
+-> printf() > stdout (serial port)
|
+->
fdprintf(fd) > file descriptor (socket, file)
|
+-> sprintf(buf, max) > string buffer
int fdprintf(int fd, const char *format,...)
Print formatted output to a file descriptor.
Domain Name Service (DNS)
DNS function signatures vary between IPv4 and IPv6 modes, but can be written to work identically in both.
DNS Function Variants
DNS Functions
|
┌──────────────────┼─────────────────┐
v v v
┌────────────────┐ ┌──────────────┐ ┌─────────────┐
│GetHostByName4()│ │GetHostByName6│ │GetHostByName│
│ │ │ │ │ │
│ IPv4 only │ │ IPv6 enabled │ │ Context- │
│ Always avail. │ │ Requires IPv6│ │ dependent │
└────────────────┘ └──────────────┘ └─────────────┘
|
v
┌─────────────────────────────┐
│ IPv4 mode: GetHostByName4() │
│ IPv6 mode: GetHostByName6() │
└─────────────────────────────┘
Universal DNS Code Pattern
Works in both IPv4 and IPv6 modes:**
"thename.com",
&resultIP,
);
printf("Resolved to: ");
resultIP.printf();
printf("\n");
}
#define DNS_OK
Success.
Definition dns.h:38
DNS Record Types
DNS Query
|
v
┌───────────────────────────────────────┐
│ Record Type Selection │
├───────────────────────────────────────┤
│
DNS_A - IPv4 address (A record) │
│
DNS_MG - Mail group resource │
└───────────────────────────────────────┘
#define DNS_MX
Mail exchange record.
Definition dns.h:53
#define DNS_AAAA
128-bit IPv6 address
Definition dns.h:54
#define DNS_A
32-bit IPv4 address
Definition dns.h:49
#define DNS_CNAME
Canonical name record.
Definition dns.h:50
#define DNS_MG
Mailing list subscriber list.
Definition dns.h:52
#define DNS_MB
Mailing list subscriber list.
Definition dns.h:51
IPv6 DNS Priority Control
GetHostByName6() supports dual-stack resolution with configurable priority:
int GetHostByName6(
const char *name,
WORD timeout,
);
Resolution Flow:**
DNS Query: "example.com"
|
v
Try TYPE1
|
┌────┴────┐
v v
Success Failure
| |
| v
| Try TYPE2
| |
| ┌────┴────┐
| v v
| Success Failure
| | |
+────+ v
| Return Error
v
Return Result
Default Behavior (IPv4 first):**
IPv6-First Resolution:**
"example.com",
&result,
);
IPv6-Only Resolution:**
"example.com",
&result,
);
DNS Resolution Strategy Matrix
┌──────────────┬────────────┬─────────────┬─────────────┐
│ Scenario │ TYPE1 │ TYPE2 │ Result │
├──────────────┼────────────┼─────────────┼─────────────┤
└──────────────┴────────────┴─────────────┴─────────────┘
Platform-Specific Considerations
macOS and BSD Systems
BSD-derived network stacks (including macOS) have specific requirements for IPv6 link-local address access.
Browser Navigation Limitation:**
Link-Local Address: fe80::203:f4ff:fe01:2347
|
v
┌────────────────────────────────────┐
│ Cannot access directly in browser │
│ BSD/macOS requirement: Scope ID │
└────────────────────────────────────┘
|
v
Required Format: fe80::203:f4ff:fe01:2347%en0
^^^
Scope ID
Scope ID Format:**
fe80::203:f4ff:fe01:2347%en0
fe80::203:f4ff:fe01:2347%en1
fe80::203:f4ff:fe01:2347%4
URL Format in Browsers:**
http:
^^ ^^^
| |
IPv6 brackets Scope ID
Common Interface Names:**
en0 - Primary Ethernet
en1 - WiFi
lo0 - Loopback
- Use
ifconfig to list available interfaces
Migration Checklist
Code Audit
┌─────────────────────────────────────────┐
│ Audit Existing IPv4 Code │
└─────────────────────┬───────────────────┘
|
┌─────────────┴─────────────┐
v v
┌──────────────────┐ ┌──────────────────┐
│ Search for: │ │ Search for: │
│ - if (ip == 0) │ │ - Function param │
│ -
IPADDR storage │ │ with 0
for IP │
│ - Null checks │ │ - Hardcoded IPs │
└──────────────────┘ └──────────────────┘
| |
v v
┌──────────────────┐ ┌──────────────────┐
│ Replace with: │ │ Replace with: │
│ - IsNull() │ │ - NullIP() │
│ - Key versioning │ │ - INADDR_ANY │
└──────────────────┘ └──────────────────┘
Storage Migration
Step 1: Add Version Key
┌──────────────────────┐
│ uint32_t version; │
└──────────────────────┘
|
v
Step 2: Check on Load
┌──────────────────────┐
│ if (version != cur) │
│ Initialize() │
└──────────────────────┘
|
v
Step 3: Save with Key
┌──────────────────────┐
│ config.version = cur │
│ SaveToFlash(config) │
└──────────────────────┘
Testing Strategy
Dual-Stack Testing Matrix:**
Test Environments
|
┌────────────────┼────────────────┐
v v v
┌─────────┐ ┌──────────┐ ┌──────────┐
│IPv4 Only│ │IPv6 Only │ │Dual Stack│
└─────────┘ └──────────┘ └──────────┘
| | |
v v v
Verify: Verify: Verify:
- Legacy ops - New features - Both modes
- Null checks - Link-local - Priority
- DNS IPv4 - DNS IPv6 - Fallback
Best Practices
Portable Code Patterns
Use GetHostByName() without version suffix:**
Always use IsNull() for comparisons:**
Use IPADDR::NullIP() for null parameters:**
Storage Design
Version-aware configuration structures:**
struct NetworkConfig {
uint32_t configVersion;
};
Always validate on load:**
void LoadConfig(NetworkConfig& cfg) {
ReadFromStorage(&cfg, sizeof(cfg));
if (cfg.configVersion != CURRENT_CONFIG_VERSION) {
InitDefaults(cfg);
SaveConfig(cfg);
}
}
DNS Resolution
Prefer IPv6 when available:**
hostname,
&result,
timeout,
);
Specify timeout appropriately:**
Summary
Key Takeaways
┌────────────────────────────────────────────────────┐
│
IPADDR is now an object, not a 32-bit integer │
├────────────────────────────────────────────────────┤
│ Use IsNull() instead of == 0 │
├────────────────────────────────────────────────────┤
│ Use NullIP() instead of 0 in parameters │
├────────────────────────────────────────────────────┤
│ IPv6 interfaces have multiple addresses │
├────────────────────────────────────────────────────┤
│ Storage size changes: 32-bit > 128-bit │
├────────────────────────────────────────────────────┤
│ Use version keys for persistent storage │
├────────────────────────────────────────────────────┤
│ DNS supports dual-stack with priority control │
├────────────────────────────────────────────────────┤
│ Link-local addresses need scope ID on BSD/macOS │
└────────────────────────────────────────────────────┘
Migration Path
Current IPv4 Code
|
v
Audit for patterns
|
v
Update null checks
|
v
Add storage versioning
|
v
Test in IPv4 mode
|
v
Test in IPv6 mode
|
v
Test dual-stack
|
v
Deploy gradually
For detailed API documentation, consult the IPADDR6 class reference in the NetBurner API documentation.