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?
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?
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 tac! printf edit (I originally posted an ugly echo -n) printf 'arpa.in-addr.%s.' "$ip" | tac -s. 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. :)
-F . should be equivalent to BEGIN{FS="."}. 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."; } Easily with Perl, thusly:
$ echo 192.168.1.1|perl -nle 'print join ".",reverse(split /\./,$_)' 1.1.168.192 perl -F'\.' -lane '$,=".";print reverse @F' 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 ruby -r ipaddr -e 'puts ...' 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 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 .Using Python’s standard library:
>>> ipaddress.ip_address('192.168.1.1').reverse_pointer '1.1.168.192.in-addr.arpa' python3.5 -c "import ipaddress; ipaddress.ip_address('192.168.1.1').reverse_pointer" (all on one line) 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.
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. 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' "{}.in-addr.arpa".format(".".join(reversed(a.split(".")))) in Python2.7 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 $ 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.
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.
#!/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 With host command from dnsutils:
$ host -t ptr 192.168.1.1 | cut -d' ' -f 2 1.1.168.192.in-addr.arpa. 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+IN\s+PTR$' 240.208.68.194.in-addr.arpa. $ dig -x 2001:db8:dc61:2a61::1 | pcregrep -o1 '^;(\S+)\s+IN\s+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. Use following one line shell:
echo '192.168.1.1' | tr '.' '\n' | tac | paste -s -d '.' - 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.
$( ... ) is to be preferred over backticks