converte o endereço IP hexadecimal em hostname

7

Gostaria de alternar entre nomes de host e endereços IP hexadecimais e vice-versa. Eu instalei syslinux-utils on Debian Stretch , que fornece gethostip :

gethostip -x google.com 
D83ACD2E

Como posso alternar D83ACD2E de volta para o nome do host?

Na versão antiga do Debian Wheezy , eu posso usar os comandos getaddrinfo' and 'getnameinfo

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

Não consegui encontrar essas ferramentas em Debian Stretch . Essas ferramentas foram substituídas por outras?

    
por Martin Vegter 27.12.2017 / 19:43

3 respostas

8

Você pode usar o getent da glibc aqui:

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

Outra abordagem perl :

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

Você pode hexificar D83ACD2E , empacotá-lo em um inteiro de 32 bits (Ordem de bytes de rede!) e, em seguida, imprimir os componentes de caractere (não assinados!) desse inteiro unidos por pontos. (Isso também é possível se um pouco mais detalhado na montagem .)

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

Com menos complicações, o sinalizador decimal para gethostip fornece esse valor diretamente, que pode ser enviado para host ou nslookup ou 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
$ 

é o registro DNS PTR associado ao endereço IP fornecido, que pode ou não ser configurado, ou pode ou não ser o nome do host que você está procurando.

Ou se você pesquisar com 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
...

mas essa versão não parece apoiar sua notação:

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

mas se o prefixo hexadecimal 0x for usado

$ socket_getnameinfo 0xD83ACD4E
Resolved address '0xD83ACD4E'

  mil04s25-in-f78.1e100.net
$ 

(de acordo com a página man, o Debian renomeou o programa, o qual eu agora lembro que o LeoNerd mencionou no IRC há um tempo atrás ...)

Se você está decidido a aceitar D83ACD4E , isso pode ser feito com o hex acima para numerificar esse valor, empacotá-lo e digitá-lo cegamente através das funções do módulo Socket . Mas isso realmente deve ser um script com verificação de erros, validação de entrada, testes, 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
$ 
    
por 27.12.2017 / 21:14
0

Resumo:

Dado que temos hexip=$(gethostip -x google.com) , podemos "usar o shell" para obter o endereço decimal quádruplo:

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

E então, use getent para obter o nome:

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

Nenhuma ferramenta adicional para instalar.

As funções para conversões numéricas de shell são fornecidas abaixo.

Descrição.

Como você tem gethostip instalado, ele também pode fornecer um endereço quádruplo decimal:

$ gethostip -d google.com.
172.217.0.174

E (não documentado) que também pode entender números de 32 bits decimais :

$ gethostip -d 100
0.0.0.100

$ gethostip -d 3627732270
216.58.205.46

Também surpreendentemente, não valores hexadecimais, ele faz como saída, mas não como entrada.
Portanto, o único problema é: converter um valor hexadecimal em um valor decimal.
Com o shell:

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

Então, em uma linha:

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

E para converter de um IP (endereço) para um PTR (nome):

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

Se você quiser fazer conversões diretamente no shell (supondo que ele permite funções), poderíamos definir essas funções:

             # 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 "$@")"; }

E todas essas conversões funcionarão:

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 "$@"    )"

Resultados em:

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 
    
por 20.09.2018 / 22:52

Tags