7

I would like to switch between hostnames and hex IP addresses, and vice versa. I have installed syslinux-utils on Debian Stretch, which provides gethostip:

gethostip -x google.com 
D83ACD2E

How can I switch D83ACD2E back to hostname?

In older version of Debian Wheezy, I can use the commands getaddrinfo' and 'getnameinfo

# getaddrinfo google.com
D83ACD4E
# getnameinfo D83ACD4E  
mil04s25-in-f14.1e100.net

I was unable to find these tools in Debian Stretch. Were these tools replaced by others?

  • If you want an answer from the official source, find out which package provides that tool in wheezy and install the same package in stretch. If it doesn't work/not the same the contact the package maintainer, they can answer the question. – apocalysque Sep 12 '18 at 22:38
8
+300

You may be able to use glibc's getent here:

$ getent ahostsv4 0xD83ACD2E | { read ip rest && getent hosts "$ip"; }
216.58.205.46   mil04s24-in-f46.1e100.net

Another perl approach:

$ perl -MSocket -le '($n)=gethostbyaddr(inet_aton("0xD83ACD2E"), AF_INET); print $n'
mil04s24-in-f46.1e100.net
15

You could hexify D83ACD2E, pack it into a (Network byte order!) 32-bit integer, then print the (unsigned!) character components of that integer joined by dots. (This is also possible if somewhat more verbose in assembly.)

$ perl -e 'printf "%v*d\n", ".", pack "N", hex shift' D83ACD2E
216.58.205.46
$ 

With fewer complications the decimal flag to gethostip gives that value directly, which then can be fed to host or nslookup or getent hosts

$ gethostip -d google.com
172.217.3.206
$ host `gethostip -d google.com`
206.3.217.172.in-addr.arpa domain name pointer sea15s12-in-f206.1e100.net.
206.3.217.172.in-addr.arpa domain name pointer sea15s12-in-f14.1e100.net.
$ getent hosts `gethostip -d google.com`
172.217.3.206   sea15s12-in-f206.1e100.net
$ 

that's the DNS PTR record associated with the given IP address, which may or may not be set, or may or may not be the hostname you are looking for.

Or if you search around with apt-file

$ sudo apt-file search getaddrinfo | grep 'getaddrinfo$'
gnulib: /usr/share/gnulib/modules/getaddrinfo
libruli-bin: /usr/bin/ruli-getaddrinfo
libsocket-getaddrinfo-perl: /usr/bin/socket_getaddrinfo
$ sudo apt-file search getnameinfo | grep 'getnameinfo$'
libsocket-getaddrinfo-perl: /usr/bin/socket_getnameinfo
$ sudo apt-get install libsocket-getaddrinfo-perl
...

but that version does not appear to support your notation:

$ socket_getnameinfo D83ACD4E
Unrecognised address or port format - Name or service not known
$ 

but does if the conventional 0x for hex prefix is used

$ socket_getnameinfo 0xD83ACD4E
Resolved address '0xD83ACD4E'

  mil04s25-in-f78.1e100.net
$ 

(according to the man page Debian did rename the program, which I now recall LeoNerd mentioning on IRC a while ago...)

If you're dead set on accepting D83ACD4E this can be done with the above hex to numify that value, packing it, and punching that blindly through Socket module functions. But this really should be a script with error checking, input validation, tests, etc

$ perl -MSocket=:addrinfo,pack_sockaddr_in \
  -E '($e,$h)=getnameinfo pack_sockaddr_in(0, pack("N", hex shift));' \
  -E 'say $h' D83ACD2E
mil04s24-in-f46.1e100.net
$ 
  • So /usr/share/gnulib/modules/getaddrinfo is not executable/the one ? – Marcus Linsner Sep 15 '18 at 22:52
0

Abstract:

Given that we have hexip=$(gethostip -x google.com) we can "use the shell" to get quad decimal address:

$ gethostip -d "$((0x$hexip))"
216.58.205.46

And then, use getent to get the name:

$ getent hosts "$(gethostip -d "$((0x$hexip))")"
216.58.205.46   mil04s24-in-f14.1e100.net

No additional tool(s) to install.

Functions for shell numeric conversions are provided below.


Description.

As you have gethostip already installed it also could give a decimal quad address:

$ gethostip -d google.com.
172.217.0.174

And (undocumented) that it also could understand decimal 32 bit numbers:

$ gethostip -d 100
0.0.0.100

$ gethostip -d 3627732270
216.58.205.46

Also surprisingly, not hex values, it does as output but not as input.
So, the only issue is: to convert an hex value to a decimal value.
With the shell:

$ echo "$((0x$hexip))"
3627732270

So, on one line:

$ gethostip -d "$((0x$hexip))"
216.58.205.46

And to convert from an IP (address) to a PTR (name):

$ getent hosts "$(gethostip -d "$((0x$hexip))")"
216.58.205.46   mil04s24-in-f14.1e100.net

If you want to do conversions directly in the shell (assuming it allows functions) we could define this functions:

             # Return decimal integer representation from a dotted-decimal.
iptoint   () {  local IFS=.; qtoint $1; }
             # Returns an hex from a dotted-decimal IP (x.x.x.x)
iptohex   () {  local IFS=.; qtohex $1; }
             # Returns dotted-decimal from a 32 bit (decimal) integer value.
inttoip   () {  echo "$(($1>>24)).$((($1>>16)&255)).$((($1>>8)&255)).$(($1&255))"; }
             # Return 32 bit (hex) value, given the decimal integer value.
inttohex  () {  printf '%X' "$1"; }
             # Return dotted-decimal IP address from a 32 bit (hex) integer value.
hextoip   () {  inttoip "$((0x$1))"; }
             # Return decimal integer representation from the 32 bit (hex) value.
hextoint  () {  echo "$((0x$1))"; }
             # Return dotted-decimal IP address from four decimal values.
qtoip     () {  (($#<4))&&return 4; inttoip "$(qtoint "$@")"; }
             # Return decimal integer value from four decimal values. 
qtoint    () {  (($#<4))&&return 4; echo "$(( ((($1)<<8|$2)<<8|$3)<<8|$4 ))"; }
             # Return hex integer value from four decimal values.
qtohex    () {  (($#<4))&&return 4; printf '%X\n' "$(qtoint "$@")"; }

And all this conversions will work:

site=google.com.
hexip=$(gethostip -x $site) || exit 4
echo "hex     = $hexip"
integer=$(hextoint "$hexip");       echo "integer = $integer"
quadIP=$( hextoip  "$hexip");       echo "quadIP  = $quadIP"

printf 'quad IP ==> integer %16s ==> %-16s\n' "$quadIP" "$(  iptoint    "$quadIP"   )"
printf 'quad IP ==> hex     %16s ==> %-16s\n' "$quadIP" "$(  iptohex    "$quadIP"   )"
printf 'integer ==> quad IP %16s ==> %-16s\n' "$integer"    "$(  inttoip    "$integer"  )"
printf 'integer ==> hex     %16s ==> %-16s\n' "$integer"    "$(  inttohex   "$integer"  )"
printf 'hex     ==> quad IP %16s ==> %-16s\n' "$hexip"  "$(  hextoip    "$hexip"    )"
printf 'hex     ==> integer %16s ==> %-16s\n' "$hexip"  "$(  hextoint   "$hexip"    )"

set -f; IFS=. eval 'set -- $quadIP'
printf 'quad    ==> quad IP %16s ==> %-16s\n' "$*"  "$(  qtoip  "$@"    )"
printf 'quad    ==> integer %16s ==> %-16s\n' "$*"  "$(  qtoint "$@"    )"
printf 'quad    ==> hex     %16s ==> %-16s\n' "$*"  "$(  qtohex "$@"    )"

Results in:

hex     = D83ACD2E
integer = 3627732270
quadIP  = 216.58.205.46
quad IP ==> integer    216.58.205.46 ==> 3627732270      
quad IP ==> hex        216.58.205.46 ==> D83ACD2E        
integer ==> quad IP       3627732270 ==> 216.58.205.46   
integer ==> hex           3627732270 ==> D83ACD2E        
hex     ==> quad IP         D83ACD2E ==> 216.58.205.46   
hex     ==> integer         D83ACD2E ==> 3627732270      
quad    ==> quad IP    216 58 205 46 ==> 216.58.205.46   
quad    ==> integer    216 58 205 46 ==> 3627732270      
quad    ==> hex        216 58 205 46 ==> D83ACD2E 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.