1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Tomato using for PPPoE connect-on-demand

Discussion in 'Tomato Firmware' started by koitsu, Apr 3, 2018.

  1. koitsu

    koitsu Network Guru Member

    While digging through code last night, I came across this in rc/services.c (I was looking at kille72, but it doesn't matter):


    if (dns->count == 0) {
            // Put a pseudo DNS IP to trigger Connect On Demand
            if (nvram_match(strcat_r(wan_prefix, "_ppp_demand", tmp), "1")) {
                    switch (get_wanx_proto(wan_prefix)) {
                    case WP_PPPOE:
                    case WP_PPP3G:
                    case WP_PPTP:
                    case WP_L2TP:
                            dnslog(LOG_DEBUG, "*** dns_to_resolv: no servers for %s: put a pseudo DNS IP to trigger Connect On Demand", wan_prefix);
                            fprintf(f, "nameserver\n");
    Toastman firmware also does this, and certainly Shibby too, so it'll need to be improved there as well. With Toastman, I think it needs to be brought in to ARM, ARM7, RT-AC, and NRT; I've forgotten what all the different branches are at this point.

    This code is literally from the very original Tomato code from Jon Zarate: https://github.com/tomatofirmware/tomato/blob/tomato/release/src/router/rc/services.c#L306 -- there's no way he would have been able to predict what has happened today, so technically it's nobody's fault, other than Jon badly choosing an IP. :)


    Starting as of a few days ago, (and also are legitimate public recursive DNS servers managed by CloudFlare alongside APNIC. They're part of and As such, probably shouldn't use as an IP to trigger PPPoE/3G/PPTP/L2TP connect-on-demand capability.

    The idea here, best I can tell, was that since is an IP address without a local route, that a DNS lookup done by a LAN client would induce dnsmasq issuing an outbound packet via WAN going "somewhere" (in this case, -- which up until a few days ago went no where), thus triggering connect-on-demand. Once the PPPoE/etc. layers were established, related protocols would actually popular /etc/resolv.dnsmasq with proper nameservers (or set whatever the user chose).

    Also, it was discovered that has "special meaning" at certain ISPs and is used internally on some Internet devices (AT&T is one, Orange (France) is another), which means for those setups connect-on-demand would possibly never get triggered on these ISPs (though I'm not sure what kind of WAN connection these services offer, so maybe not true).

    I'd suggest using or instead, and the code be commented to explain why (or just a comment with a reference to this post of mine). Some ISPs will drop/blackhole or at border routers and that's OK (the packet still goes out the WAN to trigger connect-on-demand), others will let it flow out onto the backbone where it's often dropped/blackholed. ARIN's IPv4 address space list is here (note the [11] note on the far right).

    The point is to bring up the WAN link. We don't want dnsmasq reattempting a DNS lookup for a record that will eventually hit a real recursive server -- that was never the intention. The intention was to have whatever the DNS lookup was go off into lala land/get thrown away, just enough to trigger bringing up the WAN link.
    Elfew and srouquette like this.
  2. AndreDVJ

    AndreDVJ Addicted to LI Member

    I'd use an IP as described in RFC5737 (e.g. as per the following paragraph:
    More votes anyone? is actually a legit routable IP address.
    maurer likes this.
  3. PetervdM

    PetervdM Network Guru Member

  4. koitsu

    koitsu Network Guru Member

    This in general is a good thing to be doing. I believe this is part of BCP 38. I was quite aware of this when I wrote this post, believe it or not -- it was constantly on my mind. I kept thinking of different networks that ISPs tend to filter at egress border routers thus wouldn't actually make it out onto the Internet.

    Some kind of packet must exit the WAN interface for connect-on-demand to be used. You don't want that packet to reach a real-world-used destination (especially if it's DNS, or a TCP-based protocol, because the software or stack will continue to retry it for some time).

    Using means CloudFlare is going to see and get some DNS requests that they otherwise shouldn't (and that may include things like people's own domain name for LANs -- this is bad/disclosure of private network information. dnsmasq is semi-notorious for this, and it's the main reason I myself don't use it). Using something that's IANA reserved and not locally routed/assigned means it would work for most people except those filtering egress packets on the WAN interface that are for IANA reserved CIDRs.

    We're screwed if we do and screwed if we don't. I don't know how else to get connect-on-demand to work.

    BTW, to make it easier on folks, the IANA reserved CIDR list is as follows:

    If you have ideas, I'm all ears.
  5. PetervdM

    PetervdM Network Guru Member

    two ideas, actually.
    if the only reason for the dns query is to open the connection and we are not interested in the result, we can use any public address with a bogus port - fi 54.
    the other possibility is to query the wan gateway with the standard port. almost for sure that gateway won't run a dns server.
    i don't have access to a ppp connection, so i can't try.

    for the IANA reserved address list you may add:
  6. koitsu

    koitsu Network Guru Member

    You can't "query the WAN gateway": PPPoE/PPTP/L2TP has not negotiated yet. You don't know the remote end's IP address at this time.

    Using a "bogus port" isn't possible or feasible without using iptables to redirect (or rewrite) the traffic to a different destination port, which would be a temporary situation you'd have to undo (firewall-wise) later, which could be tricky timing-wise. libc resolvers only talk DNS via port 53 (read: you cannot use something like nameserver in /etc/resolv.conf).

    Remember: the idea Tomato uses here is that dnsmasq is up and functional (though it has no Internet connectivity) -- DNS queries from LAN clients hit dnsmasq, which in turn punts the requests to, triggering connect-on-demand. Technically any kind of outbound NAT'd packet across the WAN interface should trigger connect-on-demand (ex. LAN client ICMP pinging, but Jon made the decision early on to ensure that DNS traffic also did it, hence the "bogus" address, which at the time was not a legitimate (and recursive!) resolver.

    For sake of example, using (that's in Amazon's space BTW) would accomplish the same task, and we know there's not a recursive DNS server there... as of this writing. ;-) That's why I'm discussing all of this. I'm trying to "think ahead" so that this subject doesn't have to get re-visited if someone was to go and put a recursive DNS server up on

    I guess what I'm asking is: is there a publicly-routed IP address or netblock that is literally throwing away all traffic which could be safely used for this purpose? Someone asked exactly this on superuser.com. Apparently IPv6 has this (100::/64) but IPv4 does not: https://superuser.com/questions/698244/ip-address-that-is-the-equivalent-of-dev-null -- note that the top-voted answer basically equates to what I'm discussing here, and why I proposed use of some IP in or space.

    Off-topic, but as for your IANA reserved list additions:

    Readers should be aware that the script linked to uses iptables -d for the IP matching, which means what's being looked at is the destination address. That's what's being discussed below. It matters. is for multicast. This is actually used by several different companies, especially those offering IPTV service. My general advice is not to filter this unless you know definitively your ISP and service packages are not offering multicast-aware service. It's fine to add otherwise. has been debated for some time. It's technically a broadcast-esque address (or at least was used this way in older BSD days, IIRC). This subject comes up from time to time and there's really been no "definitive" answer. The best I was ever able to find was this, referencing several RFCs: https://superuser.com/questions/388...s-from-the-network-0-0-0-0-8-used-in-practice . Generally speaking Internet-bound packets should not be within to space, but because software treats uniquely, I've always opted to not filter this.

    It should be noted that (note the netmask) is different from The latter is the default gateway placeholder. Also, in software nomenclature, a source address of is treated uniquely to act as an INADDR_ANY binding. always surprises me when I see it. This is actually used by DHCP/BOOTP in DISCOVER phase; initial DHCP advertisements come from source address port 68, with a destination address of (broadcast) port 67. So unless you have preceding firewall rules allowing destination port 67 (or alternately source port 68) traffic, I imagine this would cause problems if using an ISP which offers IP via DHCP (which, as a matter of fact, I do). I also have always opted not to filter this. Reference (last 3 paragraphs, including the quoted): http://seclists.org/nanog/2016/Sep/501
    Last edited: Apr 4, 2018
  7. PetervdM

    PetervdM Network Guru Member

    if bogus port and/or wan gateway are not possible, i agree that an address in one of the test nets is the only way to go. i would prefer an address in the range, the range *could* be re-assigned in the future because of the number of addresses it holds
    for outgoing filtering in general: i suppose someone implementing it would have enough knowledge and means to test and debug it.
    koitsu likes this.
  8. koitsu

    koitsu Network Guru Member

    This may be something I ask the folks on NANOG (as much as that mailing list is something I read, *talking* on it is a whole other ball game). If there are folks who would know the answer to this, it would be them.

    I thought about how to ask the question and this is what I came up with: is there a known IPv4 address that's publicly routed (or part of a publicly routed network) that's also known to discard any/all packets sent to it?

    That is essentially what Jon chose with It just so happens it's now an actual recursive resolver. *chuckle*

    Regardless, whatever IP address is chosen, I fully agree that if connect-on-demand is checked, somewhere in the GUI should tell the user something like "Note: wwhen the WAN link is down, DNS queries directed at the router from the LAN side will be sent to address (to allow DNS queries to trigger connect-on-demand) until the WAN comes up." Without this, serious network administrators would have no idea what exception to add to their firewall to allow the feature to work.
  9. AndreDVJ

    AndreDVJ Addicted to LI Member

  10. Sean B.

    Sean B. LI Guru Member

    What about adding an nvram variable ( such as "demand_DNSIP" ) that is set with the WAN IP anytime the WAN interface comes up and does not get replaced with an empty or NULL value when the WAN goes down, so the only time it would be an empty variable would be the very first boot ( more if a WAN connection is never made, but then what's the point for connect-on-demand anyway? ). I don't really see any case where the first WAN connection would be connect-on-demand initiated. But to be safe, protect it with a conditional that would gracefully fail a connect-on-demand attempt if demand_DNSIP is empty. Alternatively, give the variable an initial IP in defaults.c that is most likely to be a decent backup. After the WAN goes up, connect-on-demand would result in either A: you're sending the DNS demand-connect query to, what will be, your own WAN IP upon reconnect. Or B: to someone who obtained your previous WAN IP and is unlikely to be a recursive DNS server themselves, as that is rather uncommon on a dynamic IP based connection.

    Even if the majority of people that use this end up with a different WAN IP upon reconnect, no single IP would be the target of every Tomato on-demand connect query. So it spreads the bad netiquette out in a non-intrusive fashion.

    **NOTE** The existing variable "wan_ipaddr" may work for this, but I don't remember if it stays populated upon WAN disconnect.
    Last edited: Apr 7, 2018
    Elfew likes this.
  11. Elfew

    Elfew Network Guru Member

Share This Page