If we have this string (IP address): 192.168.1.1
How can I derive the (DNS reverse record form) from this string, so it will be shown like 1.1.168.192.in-addr.arpa using a shell script?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Just for curiosity value… using tac from GNU coreutils: given a variable ip in the form 192.168.1.1 then
$(printf %s "$ip." | tac -s.)in-addr.arpa
i.e.
$ ip=192.168.1.1 $ rr=$(printf %s "$ip." | tac -s.)in-addr.arpa $ echo "$rr" 1.1.168.192.in-addr.arpa
Method 2
You can do it with AWK. There are nicer ways to do it, but this is the simplest, I think.
echo '192.168.1.1' | awk 'BEGIN{FS="."}{print $4"."$3"."$2"."$1".in-addr.arpa"}'
This will reverse the order of the IP address.
Just to save a few keystrokes, as Mikel suggested, we can further shorten the upper statement:
echo '192.168.1.1' | awk -F . '{print $4"."$3"."$2"."$1".in-addr.arpa"}'
OR
echo '192.168.1.1' | awk -F. '{print $4"."$3"."$2"."$1".in-addr.arpa"}'
OR
echo '192.168.1.1' | awk -F. -vOFS=. '{print $4,$3,$2,$1,"in-addr.arpa"}'
AWK is pretty flexible. 🙂
Method 3
If you want to use only shell (zsh, ksh93, bash), here’s another way:
IFS=. read w x y z <<<'192.168.1.1' printf '%d.%d.%d.%d.in-addr.arpa.' "$z" "$y" "$x" "$w"
Or in plain old shell:
echo '192.168.1.1' | { IFS=. read w x y z; echo "$z.$y.$w.$x.in-addr.arpa."; }
Method 4
Easily with Perl, thusly:
$ echo 192.168.1.1|perl -nle 'print join ".",reverse(split /./,$_)' 1.1.168.192
Method 5
To round it out, Ruby:
ruby -r ipaddr -e 'puts IPAddr.new(ARGV.first).reverse' 192.168.1.1
Which also supports IPv6
2607:F8B0:4000:080A:0000:0000:0000:2000 => 0.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.a.0.8.0.0.0.0.4.0.b.8.f.7.0.6.2.ip6.arpa
Method 6
Through GNU sed,
sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/4.3.2.1.in-addr.arpa/g' file
It reverses any IPv4-address format.
Example:
$ echo '192.168.1.1' | sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/4.3.2.1.in-addr.arpa/g'
1.1.168.192.in-addr.arpa
$ echo '192.1.1.1' | sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/4.3.2.1.in-addr.arpa/g'
1.1.1.192.in-addr.arpa
$ echo '1.1.1.1' | sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/4.3.2.1.in-addr.arpa/g'
1.1.1.1.in-addr.arpa
$ sed -r 's/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/4.3.2.1.in-addr.arpa/g' <<< '192.168.189.23'
23.189.168.192.in-addr.arpa
Method 7
With zsh:
$ ip=192.168.1.1
$ echo ${(j:.:)${(s:.:Oa)ip}}.in-addr.arpa
1.1.168.192.in-addr.arpa
Those are variable expansion flags:
s:.:: split on.Oa: reverse order the arrayj:.:: join on.
Method 8
Using Python’s standard library:
>>> ipaddress.ip_address('192.168.1.1').reverse_pointer
'1.1.168.192.in-addr.arpa'
Method 9
Another possibility is to use the “dig” command line tool with the “-x” switch.
It actually does a request on the PTR entry, but if you filter on “PTR” it will show you one commented line (the request) and maybe some replies.
Using “dig” can be handy for a quick writing of the PTR name, without having to write a small script. Particularly if you need it interactively (to cut and paste the result).
It works on IPv6 too.
Method 10
If you want it working with IPv6 as well, you can use dig -x.
For example:
$ dig -x 194.68.208.240 | egrep '^;.*PTR$' | cut -c 2- | awk '{print $1}'
240.208.68.194.in-addr.arpa.
$ dig -x 2001:db8:dc61:2a61::1 | egrep '^;.*PTR$' | cut -c 2- | awk '{print $1}'
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.6.a.2.1.6.c.d.8.b.d.0.1.0.0.2.ip6.arpa.
Method 11
In Python
a = "192.168.1.122" import re m = re.search(r'(d+).(d+).(d+).(d+)',a) ip = m.group(4),m.group(3),m.group(2),m.group(1) '.'.join(ip) + ".in-addr.arpa" '122.1.168.192.in-addr.arpa'
Method 12
IFS=. ; set -- ${0+192.168.1.2}
printf %b. $4 $3 $2 $1 in-addr.arpa\c
IFS=. ; printf %s\n
in-addr.arpa ${0+192.168.1.2} |
sed '1!G;$s/n/./gp;h;d'
IFS=. ; printf '[%b.] '
${0+192.168.1.2.]PPPPP\c} |dc
echo in-addr.arpa
Method 13
$ while read ip
while> do
while> n=( $(echo $ip) ) && echo "${n[4]}"'.'"${n[3]}"'.'"${n[2]}"'.'"${n[1]}"'.'"in-addr.arpa"
while> done
192.168.1.2
2.1.168.192.in-addr.arpa
This way you can type in an address and hit return for your result.
Method 14
Assuming a var contains the ip: ip=192.168.2.1. If the value needs to be given to a new variable, just enclose any solution inside $() and assign that to the var rr=$(...).
Some solutions are possible:
Simplest : printf 'arpa.in-addr.%s.' "$ip" | tac -s.
Most shells: IFS=. eval 'set -- $ip'; echo "$4.$3.$2.$1.in-addr.arpa"
Some shells : IFS=. read d c b a <<<"$ip"; printf %s "$a.$b.$c.$d.in-addr.arpa."
awk : echo "$ip" | awk -F. '{OFS=FS;print $4,$3,$2,$1,"in-addr.arpa"}'
sed : echo "$ip" | sed -E 's/([^.]+).([^.]+).([^.]+).([^.]+)$/4.3.2.1.in-addr.arpa./'
sed : echo "arpa.in-addr.$ip" | sed 'y/./n/' | sed 'G;$s/n/./gp;h;d'
perl : echo "$ip" | perl -F\. -lane '$,=".";print( join(".",(reverse @F),"in-addr.arpa"))'
dig : dig -x "$ip" | awk -F '[; t]+' '/^;.*PTR$/{print($2)}'
host: host -t ptr 192.168.2.1 | cut -d' ' -f2
Both dig and host solutions work with IPv6.
Method 15
#!/bin/bash
# script file name reverseip.sh
if [ -z $1 ] || [ "help" == $1 ]
then
echo 'Convert a full ipv4 or ipv6 address to arpa notation'
echo "usage:"
echo ./reverseip.sh "help"
echo ./reverseip.sh "ipv4 address format: xxxx.xxxx.xxxx.xxxx"
echo ./reverseip.sh "ipv6 address format: xxxx:xxxx:xxxx:xxxx::xxxx"
echo "examples:"
echo ./reverseip.sh 216.58.207.35
echo ./reverseip.sh 2a00:1450:4001:824::2003
exit
fi
# if ip address passed containing ':'
if [[ $1 = *':'* ]];
then
# invert ipv6 address e.g.: 2a00:1450:4001:824::2003 to 3.0.0.2.0.0.0.0.0.0.0.0.0.0.0.0.4.2.8.0.1.0.0.4.0.5.4.1.0.0.a.2.
# @see lsowen https://gist.github.com/lsowen/4447d916fd19cbb7fce4
echo "$1" | awk -F: 'BEGIN {OFS=""; }{addCount = 9 - NF; for(i=1; i<=NF;i++){if(length($i) == 0){ for(j=1;j<=addCount;j++){$i = ($i "0000");} } else { $i = substr(("0000" $i), length($i)+5-4);}}; print}' | rev | sed -e "s/./&./g" | echo "$(</dev/stdin)ip6.arpa."
else
# invert ipv6 address e.g.: 216.58.207.35 to 35.207.58.216.in-addr.arpa
# @see Stéphane Chazelas https://unix.stackexchange.com/questions/132779/how-to-read-an-ip-address-backwards
echo $(printf %s "$1." | tac -s.)in-addr.arpa
fi
Method 16
With host command from dnsutils:
$ host -t ptr 192.168.1.1 | cut -d' ' -f 2 1.1.168.192.in-addr.arpa.
Method 17
A shorter alternative to mattbianco’s answer with less tools, but using pcregrep could be:
$ dig -x 194.68.208.240 | pcregrep -o1 '^;(S+)s+INs+PTR$' 240.208.68.194.in-addr.arpa. $ dig -x 2001:db8:dc61:2a61::1 | pcregrep -o1 '^;(S+)s+INs+PTR$' 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.6.a.2.1.6.c.d.8.b.d.0.1.0.0.2.ip6.arpa.
Method 18
Use following one line shell:
echo '192.168.1.1' | tr '.' 'n' | tac | paste -s -d '.' -
Method 19
Using POSIX sh:
$ ip=192.168.1.1
$ rev_ip=`
IFS=.
set -- $ip # set positional parameters: $1, $2, $3, ...
echo $4.$3.$2.$1.in-addr.arpa
`
$ echo $rev_ip
1.1.168.192.in-addr.arpa
Note: Be careful when setting IFS. In my example, I isolated the internal field separator (IFS) in a subshell using the backtick operator, otherwise you may have to reset/restore it.
Alternatively, you could avoid IFS and use tr instead:
$ set -- `echo $ip | tr . ` $ echo $4.$3.$2.$1.in-addr.arpa
If you’re using ksh or bash, use the $( ) subshell operator instead.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0