My previous code example for IPv4 needed a bunch of modifications to work for an IPv6 address. The thing that took me the longest to figure out was that because IPv6 seems to send a lot more ICMP messages on the local network, I needed to filter the response messages to only the type I was listening for.
bool send_ping6(const std::string& ping_ip, const std::string& HostName4Output, const bool bOutput = false)
{
bool rval = false;
if (bOutput)
std::cout << "[" << getTimeExcelLocal() << "] " << "send_ping6(" << ping_ip << ", " << HostName4Output << ");" << std::endl;
struct timespec tfs;
clock_gettime(CLOCK_MONOTONIC, &tfs);
auto ping_sockfd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
if (ping_sockfd < 0)
{
if (bOutput)
std::cout << "[" << getTimeExcelLocal() << "] " << "Socket file descriptor not received!!" << std::endl;
}
else
{
// set socket options at ip to TTL and value to 64,
// change to what you want by setting ttl_val
int ttl_val = 64;
if (setsockopt(ping_sockfd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl_val, sizeof(ttl_val)) != 0)
{
if (bOutput)
std::cerr << "[" << getTimeExcelLocal() << "] " << "Setting socket options to TTL failed!" << std::endl;
}
else
{
struct icmp6_filter filt;
ICMP6_FILTER_SETBLOCKALL(&filt);
ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt);
setsockopt(ping_sockfd, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt));
// setting timeout of recv setting
struct timeval tv_out;
tv_out.tv_sec = RECV_TIMEOUT;
tv_out.tv_usec = 0;
setsockopt(ping_sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv_out, sizeof(tv_out));
int msg_count = 0;
int flag = 1;
int msg_received_count = 0;
// send icmp packet in a loop
for (auto pingloop = 4; pingloop > 0; pingloop--)
{
// flag is whether packet was sent or not
flag = 1;
//filling packet
struct ping_pkt pckt;
bzero(&pckt, sizeof(pckt));
for (auto i = 0; i < sizeof(pckt.msg) - 1; i++)
pckt.msg[i] = i + '0';
pckt.msg[sizeof(pckt.msg) - 1] = 0;
pckt.hdr.type = ICMP6_ECHO_REQUEST;
pckt.hdr.un.echo.id = getpid();
pckt.hdr.un.echo.sequence = msg_count++;
pckt.hdr.checksum = checksum(&pckt, sizeof(pckt));
usleep(PING_SLEEP_RATE);
struct timespec time_start;
clock_gettime(CLOCK_MONOTONIC, &time_start);
struct sockaddr_in6 ping_addr;
ping_addr.sin6_family = AF_INET6;
ping_addr.sin6_port = htons(0);
inet_pton(AF_INET6, ping_ip.c_str(), &ping_addr.sin6_addr);
if (sendto(ping_sockfd, &pckt, sizeof(pckt), 0, (struct sockaddr*)&ping_addr, sizeof(ping_addr)) <= 0)
{
if (bOutput)
std::cout << "[" << getTimeExcelLocal() << "] " << "Packet Sending Failed!" << std::endl;
flag = 0;
}
//receive packet
struct sockaddr_in6 r_addr;
auto addr_len = sizeof(r_addr);
if (recvfrom(ping_sockfd, &pckt, sizeof(pckt), 0, (struct sockaddr*)&r_addr, (socklen_t*)&addr_len) <= 0 && msg_count > 1)
{
if (bOutput)
std::cout << "[" << getTimeExcelLocal() << "] " << "Packet receive failed!" << std::endl;
}
else
{
struct timespec time_end;
clock_gettime(CLOCK_MONOTONIC, &time_end);
double timeElapsed = ((double)(time_end.tv_nsec - time_start.tv_nsec)) / 1000000.0;
long double rtt_msec = (time_end.tv_sec - time_start.tv_sec) * 1000.0 + timeElapsed;
// if packet was not sent, don't receive
if (flag)
{
char szAddr[NI_MAXHOST] = { 0 };
inet_ntop(AF_INET6, &r_addr.sin6_addr, szAddr, sizeof(szAddr));
if (!(pckt.hdr.type == ICMP6_ECHO_REPLY && pckt.hdr.code == 0))
{
if (bOutput)
std::cout << "[" << getTimeExcelLocal() << "] " << "Error..Packet received from (" << szAddr << ") with ICMP type " << int(pckt.hdr.type) << " code " << int(pckt.hdr.code) << std::endl;
}
else
{
if (bOutput)
std::cout << "[" << getTimeExcelLocal() << "] " << PING_PKT_S << " bytes from (" << szAddr << ") (" << HostName4Output << ") msg_seq=" << msg_count << " ttl=" << "ttl_val" << " rtt= " << rtt_msec << " ms." << std::endl;
msg_received_count++;
}
}
}
}
rval = msg_received_count > 0;
struct timespec tfe;
clock_gettime(CLOCK_MONOTONIC, &tfe);
double timeElapsed = ((double)(tfe.tv_nsec - tfs.tv_nsec)) / 1000000.0;
long double total_msec = (tfe.tv_sec - tfs.tv_sec) * 1000.0 + timeElapsed;
if (bOutput)
std::cout << "[" << getTimeExcelLocal() << "] " << "=== " << ping_ip << " ping statistics === " << msg_count << " packets sent, " << msg_received_count << " packets received, " << ((msg_count - msg_received_count) / msg_count) * 100.0 << " percent packet loss. Total time : " << total_msec << " ms." << std::endl;
}
close(ping_sockfd);
}
return(rval);
}
Because my calling routine is keeping the addresses for the hosts as strings, I’m calling each of these routines with those strings and converting them to proper addresses inside the function. I’m making a simple choice of whether it’s an IPv4 address or an IPv6 address by the fact that IPv4 addresses have “.” in them and IPv6 addresses have “:”.
Testing possibilities with my cellular modem, I decided to try setting the PDP context to IPV6 instead of the IPV4V6 dual stack mode I had been running.
I also had to configure dhcpc to not configure the usb0 interface with an IPv4 address. Because of the way the hardware works when I didn’t make the changes to dhcpd.conf an address IPv4 was still allocated to usb0 and a route was set up, but if I tried to ping an ipv4 address on the internet I got a Destination Net Unreachable error. I configured /etc/dhcpcd.conf so the last lines tell dhcpc to only configure the usb0 interface for ipv6.
interface usb0
ipv6only
Looking at the syslog details for usb0 after a reboot of the modem and the entire system
Nov 12 11:56:20 WimPiZeroW-Wim kernel: [ 35.599281] rndis_host 1-1.1:1.0 usb0: register 'rndis_host' at usb-20980000.usb-1.1, RNDIS device, 0a:93:cc:8e:31:51
Nov 12 11:56:27 WimPiZeroW-Wim dhcpcd[252]: usb0: waiting for carrier
Nov 12 11:56:27 WimPiZeroW-Wim dhcpcd[252]: usb0: carrier acquired
Nov 12 11:56:27 WimPiZeroW-Wim dhcpcd[252]: usb0: IAID cc:8e:31:51
Nov 12 11:56:27 WimPiZeroW-Wim dhcpcd[252]: usb0: adding address fe80::64a:adc8:ebbe:d0ed
Nov 12 11:56:27 WimPiZeroW-Wim avahi-daemon[240]: Joining mDNS multicast group on interface usb0.IPv6 with address fe80::64a:adc8:ebbe:d0ed.
Nov 12 11:56:27 WimPiZeroW-Wim avahi-daemon[240]: New relevant interface usb0.IPv6 for mDNS.
Nov 12 11:56:27 WimPiZeroW-Wim avahi-daemon[240]: Registering new address record for fe80::64a:adc8:ebbe:d0ed on usb0.*.
Nov 12 11:56:27 WimPiZeroW-Wim dhcpcd[252]: usb0: soliciting an IPv6 router
Nov 12 11:56:28 WimPiZeroW-Wim dhcpcd[252]: usb0: Router Advertisement from fe80::7976:1565:680f:9a36
Nov 12 11:56:28 WimPiZeroW-Wim dhcpcd[252]: usb0: adding address 2607:fb90:8060:79e:d1b6:2c95:f26d:2e0c/64
Nov 12 11:56:28 WimPiZeroW-Wim kernel: [ 43.860443] ICMPv6: process `dhcpcd' is using deprecated sysctl (syscall) net.ipv6.neigh.usb0.retrans_time - use net.ipv6.neigh.usb0.retrans_time_ms instead
Nov 12 11:56:28 WimPiZeroW-Wim avahi-daemon[240]: Leaving mDNS multicast group on interface usb0.IPv6 with address fe80::64a:adc8:ebbe:d0ed.
Nov 12 11:56:28 WimPiZeroW-Wim avahi-daemon[240]: Joining mDNS multicast group on interface usb0.IPv6 with address 2607:fb90:8060:79e:d1b6:2c95:f26d:2e0c.
Nov 12 11:56:28 WimPiZeroW-Wim avahi-daemon[240]: Registering new address record for 2607:fb90:8060:79e:d1b6:2c95:f26d:2e0c on usb0.*.
Nov 12 11:56:28 WimPiZeroW-Wim avahi-daemon[240]: Withdrawing address record for fe80::64a:adc8:ebbe:d0ed on usb0.
Nov 12 11:56:28 WimPiZeroW-Wim dhcpcd[252]: usb0: adding route to 2607:fb90:8060:79e::/64
Nov 12 11:56:28 WimPiZeroW-Wim dhcpcd[252]: usb0: requesting DHCPv6 information
Nov 12 11:56:28 WimPiZeroW-Wim dhcpcd[252]: usb0: adding default route via fe80::7976:1565:680f:9a36
An interesting side effect of only having IPv6 on the usb0 interface while allowing it elsewhere is that while my machine is also connected to my home network it automatically routes IPv4 traffic over the wlan0 interface.
I’ve figured out I can switch between three different modem configurations on the linux system safely. 9001, 9011, and 9003. 9001 gives me qmi_wwan, 9011 gives me rndis_host, and 9003 give me cdc_mbim. RNDIS is the only one that is really plug and play on linux and produces the usb0 interface instead of wwan0. The method I’ve been configuring the device has been to connect to /dev/ttyUSB2 and issuing AT commands. When I have tried PID modes other than the ones I’ve called safe, Linux doesn’t provide /dev/ttyUSB* ports even though the device interfaces are displayed in the lsusb -t output.
Here’s what I get when I issue the command
AT+CUSBPIDSWITCH=9001,1,1
wim@WimPiZeroW-Wim:~ $ lsusb
Bus 001 Device 003: ID 1e0e:9001 Qualcomm / Option SimTech, Incorporated
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
wim@WimPiZeroW-Wim:~ $ lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 1, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 2, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 3, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 4, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 5, Class=Vendor Specific Class, Driver=qmi_wwan, 480M
wim@WimPiZeroW-Wim:~ $ ip -o a
1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever
1: lo inet6 ::1/128 scope host \ valid_lft forever preferred_lft forever
2: wwan0 inet 169.254.128.15/16 brd 169.254.255.255 scope global noprefixroute wwan0\ valid_lft forever preferred_lft forever
2: wwan0 inet6 fe80::f9:71:4f35:8ef4/64 scope link \ valid_lft forever preferred_lft forever
3: wlan0 inet 192.168.0.63/24 brd 192.168.0.255 scope global dynamic noprefixroute wlan0\ valid_lft 5335sec preferred_lft 4660sec
3: wlan0 inet6 2604:4080:1304:8010:57c0:7b33:ef3:3f35/64 scope global dynamic mngtmpaddr noprefixroute \ valid_lft 1766sec preferred_lft 1766sec
3: wlan0 inet6 fe80::2f9e:ceef:76a0:1efa/64 scope link \ valid_lft forever preferred_lft forever
AT+CUSBPIDSWITCH=9011,1,1
wim@WimPiZeroW-Wim:~ $ lsusb
Bus 001 Device 003: ID 1e0e:9011 Qualcomm / Option SimTech, Incorporated
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
wim@WimPiZeroW-Wim:~ $ lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 3, If 0, Class=Communications, Driver=rndis_host, 480M
|__ Port 1: Dev 3, If 1, Class=CDC Data, Driver=rndis_host, 480M
|__ Port 1: Dev 3, If 2, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 3, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 4, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 5, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 6, Class=Vendor Specific Class, Driver=option, 480M
wim@WimPiZeroW-Wim:~ $ ip -o a
1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever
1: lo inet6 ::1/128 scope host \ valid_lft forever preferred_lft forever
2: wlan0 inet 192.168.0.63/24 brd 192.168.0.255 scope global dynamic noprefixroute wlan0\ valid_lft 5371sec preferred_lft 4696sec
2: wlan0 inet6 2604:4080:1304:8010:57c0:7b33:ef3:3f35/64 scope global dynamic mngtmpaddr noprefixroute \ valid_lft 1767sec preferred_lft 1767sec
2: wlan0 inet6 fe80::2f9e:ceef:76a0:1efa/64 scope link \ valid_lft forever preferred_lft forever
3: usb0 inet 192.168.225.59/24 brd 192.168.225.255 scope global dynamic noprefixroute usb0\ valid_lft 43172sec preferred_lft 37772sec
3: usb0 inet6 2607:fb90:8069:ec7e:4a34:bb42:93a9:e27d/64 scope global mngtmpaddr noprefixroute \ valid_lft forever preferred_lft forever
3: usb0 inet6 fe80::b8ef:f02b:c580:1ebc/64 scope link \ valid_lft forever preferred_lft forever
AT+CUSBPIDSWITCH=9003,1,1
wim@WimPiZeroW-Wim:~ $ lsusb
Bus 001 Device 003: ID 1e0e:9003 Qualcomm / Option SimTech, Incorporated
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
wim@WimPiZeroW-Wim:~ $ lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 1, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 2, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 3, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 4, Class=Vendor Specific Class, Driver=option, 480M
|__ Port 1: Dev 3, If 5, Class=Communications, Driver=cdc_mbim, 480M
|__ Port 1: Dev 3, If 6, Class=CDC Data, Driver=cdc_mbim, 480M
wim@WimPiZeroW-Wim:~ $ ip -o a
1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever
1: lo inet6 ::1/128 scope host \ valid_lft forever preferred_lft forever
2: wwan0 inet 169.254.175.62/16 brd 169.254.255.255 scope global noprefixroute wwan0\ valid_lft forever preferred_lft forever
2: wwan0 inet6 fe80::b43f:d4a3:f985:4f33/64 scope link \ valid_lft forever preferred_lft forever
3: wlan0 inet 192.168.0.63/24 brd 192.168.0.255 scope global dynamic noprefixroute wlan0\ valid_lft 5341sec preferred_lft 4666sec
3: wlan0 inet6 2604:4080:1304:8010:57c0:7b33:ef3:3f35/64 scope global dynamic mngtmpaddr noprefixroute \ valid_lft 1764sec preferred_lft 1764sec
3: wlan0 inet6 fe80::2f9e:ceef:76a0:1efa/64 scope link \ valid_lft forever preferred_lft forever
I have configured the modem to run the way I want with the following commands
There are multiple things I’m trying to understand about networking while running in 9011 mode. It gets a global scope ipv6 address that is reachable, but that address changes on a very frequent but random time. It gets a local ipv4 address that works for traffic over the internet. Obviously the ipv4 address is being converted by NAT between the raspberry and the internet. I don’t seem to have any way of configuring how that works. The post https://www.jeffgeerling.com/blog/2022/using-4g-lte-wireless-modems-on-raspberry-pi had a Built-in AP configuration that was accessible via http. I have run nmap against the internal gateway on my platform and the only port open is DNS.
Today I ran radvdump to listen for router advertisements from the internet and then later looked at my syslog results to see what happened on the network at the corresponding times.
# radvd configuration generated by radvdump 2.18
# based on Router Advertisement from fe80::fca7:efa4:eef4:655b
# received by interface usb0
#
interface usb0
{
AdvSendAdvert on;
# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
AdvManagedFlag off;
AdvOtherConfigFlag off;
AdvReachableTime 0;
AdvRetransTimer 0;
AdvCurHopLimit 255;
AdvDefaultLifetime 0;
AdvHomeAgentFlag off;
AdvDefaultPreference medium;
AdvSourceLLAddress on;
AdvLinkMTU 1500;
prefix 2607:fb90:80ca:7753::ff00:0/0
{
AdvValidLifetime 2;
AdvPreferredLifetime 1;
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
}; # End of prefix definition
}; # End of interface definition
Nov 11 16:11:32 WimPiZeroW-Wim dhcpcd[701]: usb0: Router Advertisement from fe80::fca7:efa4:eef4:655b
Nov 11 16:11:32 WimPiZeroW-Wim dhcpcd[701]: usb0: adding address 5c5a:870:6182:d190:617e:1551:4cea:f6b6/0
Nov 11 16:11:32 WimPiZeroW-Wim dhcpcd[701]: ipv6_addaddr1: Invalid argument
Nov 11 16:11:32 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 2607:fb90:80ca:7753::ff00:0/0
Nov 11 16:11:32 WimPiZeroW-Wim dhcpcd[701]: if_route (ADD): File exists
Almost immediately afterwards:
#
# radvd configuration generated by radvdump 2.18
# based on Router Advertisement from fe80::fc89:6dff:fe67:6dde
# received by interface usb0
#
interface usb0
{
AdvSendAdvert on;
# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
AdvManagedFlag off;
AdvOtherConfigFlag off;
AdvReachableTime 0;
AdvRetransTimer 0;
AdvCurHopLimit 64;
AdvDefaultLifetime 0;
AdvHomeAgentFlag off;
AdvDefaultPreference medium;
AdvLinkMTU 1500;
prefix 2607:fb90:80ca:7753::/64
{
AdvValidLifetime 2;
AdvPreferredLifetime 1;
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
}; # End of prefix definition
RDNSS fd00:976a::9 fd00:976a::10
{
AdvRDNSSLifetime infinity; # (0xffffffff)
}; # End of RDNSS definition
}; # End of interface definition
Nov 11 16:11:33 WimPiZeroW-Wim dhcpcd[701]: usb0: Router Advertisement from fe80::fc89:6dff:fe67:6dde
Nov 11 16:11:33 WimPiZeroW-Wim dhcpcd[701]: usb0: fe80::fc89:6dff:fe67:6dde: no longer a default router
Nov 11 16:11:33 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 2607:fb90:80ca:7753::ff00:0/0
Nov 11 16:11:33 WimPiZeroW-Wim dhcpcd[701]: if_route (ADD): File exists
Nov 11 16:11:33 WimPiZeroW-Wim dhcpcd[701]: usb0: deleting default route via fe80::fc89:6dff:fe67:6dde
Nov 11 16:11:34 WimPiZeroW-Wim dhcpcd[701]: usb0: part of Router Advertisement expired
Nov 11 16:11:34 WimPiZeroW-Wim avahi-daemon[240]: Registering new address record for fe80::a3b3:ec14:47de:4692 on usb0.*.
Nov 11 16:11:35 WimPiZeroW-Wim dhcpcd[701]: usb0: expired address 2607:fb90:80ca:7753:ee71:7d12:766:2e98/64
Nov 11 16:11:35 WimPiZeroW-Wim dhcpcd[701]: usb0: part of Router Advertisement expired
Nov 11 16:11:35 WimPiZeroW-Wim dhcpcd[701]: usb0: deleting route to 2607:fb90:80ca:7753::/64
Nov 11 16:11:35 WimPiZeroW-Wim avahi-daemon[240]: Withdrawing address record for 2607:fb90:80ca:7753:ee71:7d12:766:2e98 on usb0.
Nov 11 16:11:35 WimPiZeroW-Wim avahi-daemon[240]: Leaving mDNS multicast group on interface usb0.IPv6 with address 2607:fb90:80ca:7753:ee71:7d12:766:2e98.
Nov 11 16:11:35 WimPiZeroW-Wim avahi-daemon[240]: Joining mDNS multicast group on interface usb0.IPv6 with address fe80::a3b3:ec14:47de:4692.
And a couple of minutes later:
# radvd configuration generated by radvdump 2.18
# based on Router Advertisement from fe80::fc89:6dff:fe67:6dde
# received by interface usb0
#
interface usb0
{
AdvSendAdvert on;
# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
AdvManagedFlag off;
AdvOtherConfigFlag on;
AdvReachableTime 0;
AdvRetransTimer 0;
AdvCurHopLimit 64;
AdvDefaultLifetime 65535;
AdvHomeAgentFlag off;
AdvDefaultPreference medium;
AdvLinkMTU 1500;
prefix 2607:fb90:80c8:82f8::/64
{
AdvValidLifetime infinity; # (0xffffffff)
AdvPreferredLifetime infinity; # (0xffffffff)
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
}; # End of prefix definition
RDNSS fd00:976a::9 fd00:976a::10
{
AdvRDNSSLifetime infinity; # (0xffffffff)
}; # End of RDNSS definition
}; # End of interface definition
Nov 11 16:13:42 WimPiZeroW-Wim dhcpcd[701]: usb0: Router Advertisement from fe80::fc89:6dff:fe67:6dde
Nov 11 16:13:42 WimPiZeroW-Wim dhcpcd[701]: usb0: adding address 2607:fb90:80c8:82f8:b87a:2c7a:ae2e:7e0e/64
Nov 11 16:13:42 WimPiZeroW-Wim avahi-daemon[240]: Leaving mDNS multicast group on interface usb0.IPv6 with address fe80::a3b3:ec14:47de:4692.
Nov 11 16:13:43 WimPiZeroW-Wim avahi-daemon[240]: Joining mDNS multicast group on interface usb0.IPv6 with address 2607:fb90:80c8:82f8:b87a:2c7a:ae2e:7e0e.
Nov 11 16:13:43 WimPiZeroW-Wim avahi-daemon[240]: Registering new address record for 2607:fb90:80c8:82f8:b87a:2c7a:ae2e:7e0e on usb0.*.
Nov 11 16:13:43 WimPiZeroW-Wim avahi-daemon[240]: Withdrawing address record for fe80::a3b3:ec14:47de:4692 on usb0.
Nov 11 16:13:43 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 2607:fb90:80c8:82f8::/64
Nov 11 16:13:43 WimPiZeroW-Wim dhcpcd[701]: usb0: adding default route via fe80::fc89:6dff:fe67:6dde
Then it went almost a couple of hours before more changes to the network
Nov 11 18:01:54 WimPiZeroW-Wim dhcpcd[701]: usb0: Router Advertisement from fe80::c1e7:222d:69eb:c90c
Nov 11 18:01:54 WimPiZeroW-Wim dhcpcd[701]: usb0: adding address 5c5a:870:6182:d190:617e:1551:4cea:f6b6/0
Nov 11 18:01:54 WimPiZeroW-Wim dhcpcd[701]: ipv6_addaddr1: Invalid argument
Nov 11 18:01:54 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 2607:fb90:80c8:82f8::ff00:0/0
Nov 11 18:01:54 WimPiZeroW-Wim dhcpcd[701]: if_route (ADD): File exists
Nov 11 18:01:55 WimPiZeroW-Wim dhcpcd[701]: usb0: Router Advertisement from fe80::fc89:6dff:fe67:6dde
Nov 11 18:01:55 WimPiZeroW-Wim dhcpcd[701]: usb0: fe80::fc89:6dff:fe67:6dde: no longer a default router
Nov 11 18:01:55 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 2607:fb90:80c8:82f8::ff00:0/0
Nov 11 18:01:55 WimPiZeroW-Wim dhcpcd[701]: if_route (ADD): File exists
Nov 11 18:01:55 WimPiZeroW-Wim dhcpcd[701]: usb0: deleting default route via fe80::fc89:6dff:fe67:6dde
Nov 11 18:01:56 WimPiZeroW-Wim dhcpcd[701]: usb0: part of Router Advertisement expired
Nov 11 18:01:56 WimPiZeroW-Wim avahi-daemon[240]: Registering new address record for fe80::a3b3:ec14:47de:4692 on usb0.*.
Nov 11 18:01:57 WimPiZeroW-Wim dhcpcd[701]: usb0: expired address 2607:fb90:80c8:82f8:b87a:2c7a:ae2e:7e0e/64
Nov 11 18:01:57 WimPiZeroW-Wim dhcpcd[701]: usb0: part of Router Advertisement expired
Nov 11 18:01:57 WimPiZeroW-Wim dhcpcd[701]: usb0: deleting route to 2607:fb90:80c8:82f8::/64
Nov 11 18:01:57 WimPiZeroW-Wim avahi-daemon[240]: Withdrawing address record for 2607:fb90:80c8:82f8:b87a:2c7a:ae2e:7e0e on usb0.
Nov 11 18:01:57 WimPiZeroW-Wim avahi-daemon[240]: Leaving mDNS multicast group on interface usb0.IPv6 with address 2607:fb90:80c8:82f8:b87a:2c7a:ae2e:7e0e.
Nov 11 18:01:57 WimPiZeroW-Wim avahi-daemon[240]: Joining mDNS multicast group on interface usb0.IPv6 with address fe80::a3b3:ec14:47de:4692.
Nov 11 18:04:04 WimPiZeroW-Wim dhcpcd[701]: usb0: Router Advertisement from fe80::fc89:6dff:fe67:6dde
Nov 11 18:04:04 WimPiZeroW-Wim dhcpcd[701]: usb0: adding address 2607:fb90:80c3:42cc:11b:d753:e52a:40bb/64
Nov 11 18:04:04 WimPiZeroW-Wim avahi-daemon[240]: Leaving mDNS multicast group on interface usb0.IPv6 with address fe80::a3b3:ec14:47de:4692.
Nov 11 18:04:04 WimPiZeroW-Wim avahi-daemon[240]: Joining mDNS multicast group on interface usb0.IPv6 with address 2607:fb90:80c3:42cc:11b:d753:e52a:40bb.
Nov 11 18:04:04 WimPiZeroW-Wim avahi-daemon[240]: Registering new address record for 2607:fb90:80c3:42cc:11b:d753:e52a:40bb on usb0.*.
Nov 11 18:04:04 WimPiZeroW-Wim avahi-daemon[240]: Withdrawing address record for fe80::a3b3:ec14:47de:4692 on usb0.
Nov 11 18:04:04 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 2607:fb90:80c3:42cc::/64
Nov 11 18:04:04 WimPiZeroW-Wim dhcpcd[701]: usb0: adding default route via fe80::fc89:6dff:fe67:6dde
Nov 11 18:29:11 WimPiZeroW-Wim dhcpcd[701]: usb0: failed to renew DHCP, rebinding
Nov 11 18:29:11 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 192.168.225.0/24
Nov 11 18:29:11 WimPiZeroW-Wim dhcpcd[701]: usb0: adding default route via 192.168.225.1
ov 11 19:52:16 WimPiZeroW-Wim dhcpcd[701]: usb0: Router Advertisement from fe80::459a:7427:b0ae:7848
Nov 11 19:52:16 WimPiZeroW-Wim dhcpcd[701]: usb0: adding address 5c5a:870:6182:d190:617e:1551:4cea:f6b6/0
Nov 11 19:52:16 WimPiZeroW-Wim dhcpcd[701]: ipv6_addaddr1: Invalid argument
Nov 11 19:52:16 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 2607:fb90:80c3:42cc::ff00:0/0
Nov 11 19:52:16 WimPiZeroW-Wim dhcpcd[701]: if_route (ADD): File exists
Nov 11 19:52:18 WimPiZeroW-Wim dhcpcd[701]: usb0: Router Advertisement from fe80::fc89:6dff:fe67:6dde
Nov 11 19:52:18 WimPiZeroW-Wim dhcpcd[701]: usb0: fe80::fc89:6dff:fe67:6dde: no longer a default router
Nov 11 19:52:18 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 2607:fb90:80c3:42cc::ff00:0/0
Nov 11 19:52:18 WimPiZeroW-Wim dhcpcd[701]: if_route (ADD): File exists
Nov 11 19:52:18 WimPiZeroW-Wim dhcpcd[701]: usb0: deleting default route via fe80::fc89:6dff:fe67:6dde
Nov 11 19:52:18 WimPiZeroW-Wim dhcpcd[701]: usb0: part of Router Advertisement expired
Nov 11 19:52:19 WimPiZeroW-Wim avahi-daemon[240]: Registering new address record for fe80::a3b3:ec14:47de:4692 on usb0.*.
Nov 11 19:52:20 WimPiZeroW-Wim dhcpcd[701]: usb0: expired address 2607:fb90:80c3:42cc:11b:d753:e52a:40bb/64
Nov 11 19:52:20 WimPiZeroW-Wim dhcpcd[701]: usb0: part of Router Advertisement expired
Nov 11 19:52:20 WimPiZeroW-Wim dhcpcd[701]: usb0: deleting route to 2607:fb90:80c3:42cc::/64
Nov 11 19:52:20 WimPiZeroW-Wim avahi-daemon[240]: Withdrawing address record for 2607:fb90:80c3:42cc:11b:d753:e52a:40bb on usb0.
Nov 11 19:52:20 WimPiZeroW-Wim avahi-daemon[240]: Leaving mDNS multicast group on interface usb0.IPv6 with address 2607:fb90:80c3:42cc:11b:d753:e52a:40bb.
Nov 11 19:52:20 WimPiZeroW-Wim avahi-daemon[240]: Joining mDNS multicast group on interface usb0.IPv6 with address fe80::a3b3:ec14:47de:4692.
Nov 11 19:52:27 WimPiZeroW-Wim systemd[1]: session-3.scope: Succeeded.
Nov 11 19:52:27 WimPiZeroW-Wim systemd[1]: session-3.scope: Consumed 24.275s CPU time.
Nov 11 19:54:27 WimPiZeroW-Wim dhcpcd[701]: usb0: Router Advertisement from fe80::fc89:6dff:fe67:6dde
Nov 11 19:54:27 WimPiZeroW-Wim dhcpcd[701]: usb0: adding address 2607:fb90:8069:47ff:69ad:1e37:6fb5:7fa0/64
Nov 11 19:54:27 WimPiZeroW-Wim dhcpcd[701]: usb0: adding route to 2607:fb90:8069:47ff::/64
Nov 11 19:54:27 WimPiZeroW-Wim dhcpcd[701]: usb0: adding default route via fe80::fc89:6dff:fe67:6dde
Nov 11 19:54:27 WimPiZeroW-Wim avahi-daemon[240]: Leaving mDNS multicast group on interface usb0.IPv6 with address fe80::a3b3:ec14:47de:4692.
Nov 11 19:54:27 WimPiZeroW-Wim avahi-daemon[240]: Joining mDNS multicast group on interface usb0.IPv6 with address 2607:fb90:8069:47ff:69ad:1e37:6fb5:7fa0.
Nov 11 19:54:27 WimPiZeroW-Wim avahi-daemon[240]: Registering new address record for 2607:fb90:8069:47ff:69ad:1e37:6fb5:7fa0 on usb0.*.
Nov 11 19:54:27 WimPiZeroW-Wim avahi-daemon[240]: Withdrawing address record for fe80::a3b3:ec14:47de:4692 on usb0.
I do not understand why it gets router advertisements that change as frequently as it does, and especially why sometimes it gets a /0 prefix occasionally.
Here is a series of commands I’ve found useful to checking status on the modem
If you have any suggestions to make my networking more stable, I would appreciate any help. When I tried these two PID modes I lost access to the ttyUSB ports and had to connect the device to a windows machine, force install questionable drivers for the device and then issue commands to reset the modem back to a PID mode I could work with. I would also appreciate any information on how to send AT commands to a USB port/device/interface if the operating system didn’t install tty drivers to make it easily accessible.
AT+CUSBPIDSWITCH=9002,1,1
wim@WimPiZeroW-Wim:~ $ lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 4, If 0, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 4, If 1, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 4, If 2, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 4, If 3, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 4, If 4, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 4, If 5, Class=Vendor Specific Class, Driver=, 480M
AT+CUSBPIDSWITCH=9018,1,1
wim@WimPiZeroW-Wim:~ $ lsusb
Bus 001 Device 003: ID 1e0e:9018 Qualcomm / Option SimTech, Incorporated
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
wim@WimPiZeroW-Wim:~ $ lsusb -t
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 3, If 1, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 3, If 2, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 3, If 3, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 3, If 4, Class=Vendor Specific Class, Driver=, 480M
|__ Port 1: Dev 3, If 5, Class=Communications, Driver=cdc_ether, 480M
|__ Port 1: Dev 3, If 6, Class=CDC Data, Driver=cdc_ether, 480M
My apartment has three options for high speed internet. Centurylink, Xfinity, and Astound Broadband. When I moved in I chose Wave Broadband because I’d had good experience in the past with Condointernet and it later became Wave Broadband. Now they seem to be going with the moniker Astound Broadband powered by Wave. One of the features that I’ve used in the past and am using now is their support of IPv6.
I’ve had occasional hiccups in my networking, most often recently the IPv4 networking stops working while the IPv6 network is still working. It has some interesting effects, such as my browser connected to gmail.com working fine but hitting a link on a web page in an email that goes to an IPv4 only address not working. Usually the problem can be fixed by connecting to my router and having it release its external IPv4 DHCP address and requesting a new lease. Occasionally there are problems on the ISP side of things that make things more problematic. Last week when I was having problems, I managed to mess up my IPv6 configuration and then spent a long time figuring out what the problem was. I’m writing this up mainly as a suggestion for a reliable working configuration.
I’m running DDWRT on a Netgear R7000 router. It’s somewhat strange, as it seems there’s no real release, only betas. It explicitly says go look at the directory structure and “DO NOT USE THE ROUTER DATABASE.” I’ve run it in various incarnations for well over a decade.
DD-WRT Basic Setup
The Basic IPv4 page is very standard, naming my local network and router and picking the IPv4 address range I want to use locally. I’ve generally been using the same address block since they were defined in RFC1918, though that’s been superseded by newer RFC’s. Wikipedia has a good description of private address space.
DD-WRT IPv6 Setup
I’m enabling IPv6 and seelcting DHCPv6 with Prefix Delegation. I’ve left all of the other items on this page either blank or at their defaults.
The way IPv6 hosts generally allocate global addresses in stateless mode is that they recognize router advertisements arriving on the network port and configure their own address based on information received. They then broadcast locally to make sure there are no address collisions. This may be a significant oversimplification, but it’s a useful one.
Initially I had the Router Advertisement Daemon enabled on this page but have since changed to use DNSMASQ for router advertisements since it’s already doing so much of the work on the router. Part of the reason I stopped using radvd was also based on the fact that I was trying to add two static DNS entries for IPv6 in the fields on this page. I was adding the google IPv6 DNS entries of 2001:4860:4860::8888 and 2001:4860:4860::8844. The problem I was running into was that DDWRT was creating a radvd.conf file that included the two static DNS servers I listed while also including the DNS servers inherited from the advertisement it received from my ISP router. Radvd was seeing more than three DNS servers and exiting with an error. This meant that no router advertisements were being broadcast on my local network. I’d been looking at the configuration of the radvd deamon with the command cat /tmp/radvd.conf in my terminal window. I asked questions about this over on the DDWRT forums as well as opening an issue with the radvd software itself. The slightly unhelpful answer to my question told me to use dnsmasq for router advertisements. I’d tried that by adding the enable-ra option but never succeeded in having my machines get global IPv6 addresses.
DD-WRT Services DNSMasq Additional Options
I finally came across a set of options that I needed to get dnsmasq to broadcast router advertisements that are recognized by hosts on my local network to have them configure IPv6 global addresses.
In the terminal window of DDWRT I can dump the contents of the dnsmasq configuration file with the command cat /tmp/dnsmasq.conf. In doing so, I see what DDWRT writes to the configuration followed by my own customizations. When I do that I see multiple dhcp-range= lines, which initially confused me, but seems to work properly. The first is the IPv4 range and lease time, while the second is the IPv6 information from my “Additional Options” entry.
The tool I’ve used to diagnose my router advertisment issues has been radvdump. It seems to be available on most linux distributions as well as being on ddwrt. When I was running it on my router and the router was not sending out its own advertisments, I’d get messages from my ISP that looked like this:
# radvd configuration generated by radvdump 2.19
# based on Router Advertisement from fe80::22c:c8ff:fe42:24bf
# received by interface vlan2
#
interface vlan2
{
AdvSendAdvert on;
# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
AdvManagedFlag off;
AdvOtherConfigFlag on;
AdvReachableTime 0;
AdvRetransTimer 0;
AdvCurHopLimit 64;
AdvDefaultLifetime 1800;
AdvHomeAgentFlag off;
AdvDefaultPreference high;
AdvSourceLLAddress on;
AdvLinkMTU 1500;
prefix 2604:4080:1304::/64
{
AdvValidLifetime 2592000;
AdvPreferredLifetime 604800;
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
}; # End of prefix definition
}; # End of interface definition
When I was successfully running radvd on ddwrt, I never saw its own advertisements but could see them on other machines on my local network. Now that I’m using dnsmasq for my advertisements, I see messages on the router itself.
# radvd configuration generated by radvdump 2.19
# based on Router Advertisement from fe80::b27f:b9ff:fe83:6591
# received by interface br0
#
interface br0
{
AdvSendAdvert on;
# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
AdvManagedFlag off;
AdvOtherConfigFlag on;
AdvReachableTime 0;
AdvRetransTimer 0;
AdvCurHopLimit 64;
AdvDefaultLifetime 300;
AdvHomeAgentFlag off;
AdvDefaultPreference medium;
AdvLinkMTU 1500;
AdvSourceLLAddress on;
prefix 2604:4080:1304:8010::/64
{
AdvValidLifetime 300;
AdvPreferredLifetime 300;
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
}; # End of prefix definition
DNSSL wimsworld.com wimsworld.local local
{
AdvDNSSLLifetime 300;
}; # End of DNSSL definition
RDNSS fe80::b27f:b9ff:fe83:6591
{
AdvRDNSSLifetime 300;
}; # End of RDNSS definition
}; # End of interface definition
I looked at the radvdump output from a friend’s location where he’s on XFinity and IPv6 just seems to be configured and works and this is what I saw. This is from a client machine since he has no access to the Xfinity supplied router itself.
# radvd configuration generated by radvdump 2.17
# based on Router Advertisement from fe80::16c0:3eff:fe4e:400c
# received by interface wlan0
#
interface wlan0
{
AdvSendAdvert on;
# Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
AdvManagedFlag on;
AdvOtherConfigFlag on;
AdvReachableTime 0;
AdvRetransTimer 0;
AdvCurHopLimit 64;
AdvDefaultLifetime 180;
AdvHomeAgentFlag off;
AdvDefaultPreference medium;
AdvSourceLLAddress on;
RDNSS 2001:558:feed::1 2001:558:feed::2
{
AdvRDNSSLifetime 180;
}; # End of RDNSS definition
prefix 2601:603:4c7f:41e0::/64
{
AdvValidLifetime 300;
AdvPreferredLifetime 300;
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
}; # End of prefix definition
route ::/0
{
AdvRoutePreference medium;
AdvRouteLifetime 180;
}; # End of route definition
}; # End of interface definition
When IPv6 is working properly on my router I have a globally scoped IPv6 address on my vlan2 interface and one on my br0 interface. I can recognize that my vlan2 interface is the outside world because the IPv4 address associated with it is a routable IPv4 address while the IPv4 address associated with br0 is 192.168.0.1.
I learned a lot about how IPv6 allocates addresses during this process, A bunch of the resources I used came from this set of locations.
I’ve been wanting to use a dynamic address in my personal domain and IPv6. While I read that it should be possible, finding the exact method of configuring ddclient to do so was not obvious to me. The default installation configures everything to register an IPv4 address and finding specific configuration examples using IPv6 was hard. It turns out that finding examples was hard because the process itself is easy.
Go to domains.google.com, configure your domain to include dynamic DNS hosts, add the hostname you want to register, and retrieve the specific credentials for that hostname. There are help pages describing that process at google. It will create a record with the hostname you specify, and an A record (IPv4) with a 1 minute time to live.
Google Domains
Install ddclient using apt and go through the debconf wizard to enter the credentials. It will set up the default configuration using IPv4.
sudo apt install ddclient -ydomains.googleddclient –force –verbose to see if errors occurGoogle Domains IPv4 address registered
Manually editing /etc/ddclient.conf and changing the use= statement to usev6= and running ddclient a second time will switch to registering the IPv6 address.
another ddclient –force –verbose to confirm changes didn’t create errors
running sudo systemctl confirms that ddclient.service is loaded active and running. If the address were to change, it should automatically be updated in the dynamic domain entry.