Inconsistent octal madness

$ ping 010
PING 010 (0.0.0.8) 56(84) bytes of data.
$ ping 010.1.1.1
PING 010.1.1.1 (8.1.1.1) 56(84) bytes of data.
$ ping 018
ping: 018: Name or service not known
$ ping 18
PING 18 (0.0.0.18) 56(84) bytes of data.
$ ping 018.1.1.1
PING 018.1.1.1 (18.1.1.1) 56(84) bytes of data.
$ ping 18.1.1.1
PING 18.1.1.1 (18.1.1.1) 56(84) bytes of data.

I'm sitting here trying to make sure the #curl URL parser acts consistently. Which certainly is a challenge...
This is where I scratch my head: https://github.com/curl/curl/pull/16652
urlapi: treat 0 alone as decimal number in IPv4 address by bagder · Pull Request #16652 · curl/curl

Not as a broken octcal. Regression from b4538ec Extended test 1560 to verify this behavior.

GitHub

@bagder you have indeed a strange debian. I can't reproduce decimal conversion with leading 0 on debian testing, either.
Does nsswitch.conf play a role in parsing ip address notation? Or is this only depended on ping version?

I would vote for not accepting any non-decimal notations. Neither octal, nor hex, nor anything else.

@lbehm I can't remove support for octal/hex without breaking use cases - so I won't
@bagder On the upside, if you get curl's URL parser to act consistently it may be the very first one ever. Something to look forward to?
ok sorry, embarrassingly enough it was misdiagnosed by me. It is my silly DNS server that "helpfully" resolves these names for me!
@bagder
No worries at all! DNS issues can be sneaky like that. Glad you figured it out!

@bagder I'm not sure it's DNS, it could be earlier in the local functions to handle IP addresses in different notations (I am not going to embarrass myself by naming these functions to you).

That will make things like

$ ping 0x7f000001
PING 0x7f000001 (127.0.0.1) 56(84) bytes of data.

$ ping 0177.0.0.1
PING 0177.0.0.1 (127.0.0.1) 56(84) bytes of data.

work without ever hitting the resolver.

@KHoos @bagder

Even those "local functions" are part of "the resolver".

(Back when I did some professional tooling and troubleshooting, I couldn't stress enough to my colleagues that PING is the worst possible way to "find out" things about internet connections. Instead, use #curl and fetch an HTTPS domain for a site that actually interests you.)

@KHoos I am sure it is the DNS. Using ltrace I could see how 018.1.1.1 gets a 0 back from the getaddrinfo() call. I can also reproduce it with dig directly.

The precise point was to use 018 as the first number, as that is 0-prefixed but not a valid octal.

@bagder All of those except 018.1.1.1 get resolved directly by the OS for me.

root@592cda340524:/# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux trixie/sid"
NAME="Debian GNU/Linux"
VERSION_CODENAME=trixie
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
root@592cda340524:/# grep hosts: /etc/nsswitch.conf
hosts: files
root@592cda340524:/# getent ahosts 010
0.0.0.8 STREAM 010
0.0.0.8 DGRAM
0.0.0.8 RAW
root@592cda340524:/# getent ahosts 010.1.1.1
8.1.1.1 STREAM 010.1.1.1
8.1.1.1 DGRAM
8.1.1.1 RAW
root@592cda340524:/# getent ahosts 018
root@592cda340524:/# echo $?
2
root@592cda340524:/# getent ahosts 18
0.0.0.18 STREAM 18
0.0.0.18 DGRAM
0.0.0.18 RAW
root@592cda340524:/# getent ahosts 018.1.1.1
root@592cda340524:/# echo $?
2
root@592cda340524:/# getent ahosts 18.1.1.1
18.1.1.1 STREAM 18.1.1.1
18.1.1.1 DGRAM
18.1.1.1 RAW
root@592cda340524:/#

Debian -- The Universal Operating System

Debian is an operating system and a distribution of Free Software. It is maintained and updated through the work of many users who volunteer their time and effort.

@bagder which DNS server/cache converts names to IP address this way?
@pemensik I did not dig very deep. The closest is my ASUS router's DNS, I didn't check if it is this or next hop that does this craziness. Doesn't matter to me.
@bagder can you send "dig ch txt version.bind" query to it? I expect Dnsmasq of sort. inet_pton() accepts only well specified addresses. inet_aton() accepted almost any random garbage and should be avoided and replaced. Is it possible your ping uses the old call?
@pemensik this is a very recent ping and glibc. As you can see in the thread, all pings on all platforms work like this too - except for the name my DNS tricked me to misunderstand.
@bagder ooh. At least python socket module considers getaddrinfo ('127.1', 0, flags=AI_NUMERICHOST) or even '0x7f.1' as completely valid thing. Expected such legacy crap would get refused, but getaddrinfo does not enforce full IPv4.
@bagder if it helps - I spent an entire day finding out I had misplaced a semi colon in rust the other day ... oh how our AI spawn will laugh at our follies ...
@bagder Well, 018 isn't legal octal so it can only reasonably be interpreted as decimal or an error
@RandomDamage @bagder I'd argue, as long as the 0-prefix is interpreted as octal (which in and of itself is a terrible footgun that never should have happened), the only reasonable interpretation should be an error. And not just any error, an explicit "invalid argument" error and none other.

@bagder personally, I think we're far enough past octal being in common usage in IT that it shouldn't be an automatic interpretation anymore, which would make interpreting 010 as 8 the wrong thing to do

It's *much* more likely to be left-padded decimal by intent than actual octal

@bagder Is it a joke?

(I mean, you have certainly realised that 018 is not an octal number?)

@bagder OK it looked consistent until the second to last one...
@bagder This looks like a bug in your host's stdlib. With #musl on Alpine I get an error for 018.1.1.1, as expected.
@dalias @bagder Can confirm broken behaviour under glibc 2.39 on Ubuntu 24.04 (default resolver config w/ systemd-resolved).
@astraleureka @bagder Random cursed guess: It's systemd making it do the wrong thing, via some cursed NSS module.
@dalias @astraleureka as mentioned elsewhere in this thread, it's my DNS that is "helpful"!
@bagder @astraleureka It's cursed that this is even making it to DNS...
@dalias @astraleureka it is actually a pretty weak design that an IP address with wrong syntax is instead treated as a hostname and just passed along instead of outright rejected.
@astraleureka @bagder Guess of mechanism: after resolving as a numeric address (rightly) fails with the standard processing, it gets passed on to next NSS backend in the order. Systemd (or something) has provided one which also resolves aaa.bbb.ccc.ddd (but not just aaaaaaaaaaaa form) to numeric IPv4, but forcibly treats all fields as decimal contrary to the RFC and POSIX. Hilarity ensues.
@dalias @bagder nss providers are just "files dns" as per defaults, but resolv.conf points to localhost. systemd-resolved synthesised an A record (*and* an NXDOMAIN) for 018.0.0.0 for some ungodly reason, but only on the first attempt. subsequent attempts seemed to have cached the NXDOMAIN. this is wildly broken

@dalias @bagder sdmzsapnsp01:/etc/bind root$ host 018.0.0.0
018.0.0.0 has address 18.0.0.0
Host 018.0.0.0 not found: 3(NXDOMAIN)

Help, I'm nauseous.

@dalias @bagder Even more batshit:

sdmzsapnsp01:/etc/bind root$ host 019.011.012.004 019.011.012.004 has address 19.11.12.4

@astraleureka @dalias when the first number is a "bad octal", they all become decimal?
@astraleureka @dalias @bagder I really need to get back to working on shibari-cache, but WHEN goddammit
@bagder Maybe you used an uppercase zero? ;-p