Traduccion entre Direcciones IP y Nombres

Traducción de Nombre a IP

El programa que sigue resuelve los nombres de máquinas a su direccion IP:

lhp@nereida:~/Lperl/src/perl_networking/ch3$ ip_trans.pl
www.google.com
www.google.com => 209.85.135.103
www.yahoo.com
www.yahoo.com => 69.147.114.210
www.upc.es
www.upc.es => 147.83.194.21
lhp@nereida:~/Lperl/src/perl_networking/ch3$ cat -n ip_trans.pl
  1  #!/usr/bin/perl
  2  use strict;
  3  use Socket;
  4
  5  while (<>) {
  6      chomp;
  7      my $packed_address = gethostbyname($_);
  8      unless ($packed_address) {
  9          print "$_ => ?\n";
 10          next;
 11      }
 12      my $dotted_quad    = inet_ntoa($packed_address);
 13      print "$_ => $dotted_quad\n";
 14  }

La Función gethostbyname

La llamada $packed_address = gethostbyname($name) devuelve - en un contexto escalar- un escalar que contiene una estructura empaquetada que describe la dirección. En un contexto de lista gethostbyname devuelve 5 elementos:

pp2@nereida:/tmp/UnixProcess-Composition-Simple-0.01/script$ perl -wde 0
main::(-e:1):   0
  DB<1> @a = gethostbyname('www.google.com')
  DB<2> x @a
0  'www.l.google.com' # canonical hostname: nombre oficial
1  'www.google.com'   # alias (separados por espacios)
2  2                  # tipo de dirección: AF_INET
3  4                  # longitud de la dirección empaquetada
4  'ÑUg'              # dirección empaquetada 0
5  'ÑUh'              # dirección empaquetada 1
6  'ÑUc'              # dirección empaquetada 2
7  'ÑU'               # dirección empaquetada 3

Las Funciones pack y unpack

La función pack recibe una cadena de formato y una lista de argumentos y empaqueta dichos argumentos según la descripción dada en la cadena de formato. La cadena de formato esta compuesta a partir de letras que denotan diversos tipos y representación:

Formato Descripción
c,C char (entero de 8 bits).
s,S short, 16 bits.
l,L long, 32 bits.
q,Q quad (64 bits).
i,I entero con signo, formato nativo.
n,N Un valor de 16 ó 32 bits (big-endian).
v,V Un valor de 16 ó 32 bits (orden "VAX" o little-endian).
a,A Cadena rellena con caracteres nulos/espacios.
b,B Cadena de bits con órdenes de bits ascendiente o descendiente.
h,H Cadena hexadecimal, Nibble alto o bajo primero.
Z Cadena terminada con un carácter nulo.

Ejemplos:

  DB<1> $b = pack "c s l", 31, 1000, 4320033
  DB<2> ($c, $s, $n) = unpack "c s l", $b
  DB<4> x ($c, $s, $n)
0  31
1  1000
2  4320033
La letra de formato puede cualificarse con un número para indicar repetición:
 DB<1> $b = pack "c2 s3 c5", 31, 24, 1000..1002, ord('A')..ord('E')
 DB<2> x unpack "c2 s3 c5", $b
0  31
1  24
2  1000
3  1001
4  1002
5  65
6  66
7  67
8  68
9  69
En los formatos alfabéticos (como a8) el número no indica repetición. Indica que la cadena "a" se rellena con caracteres nulos hasta tener tamaño 8:
  DB<1> $b = pack "a8", "hola"
  DB<2> x $b
0  "hola\c@\c@\c@\c@"
  DB<3> p $b
hola
Es posible cualificar la letra con un asterisco para indicar que el formato se puede usar tantas veces como se quiera para empaquetar los restantes items:
  DB<5> $b = pack "s*", 31, 1000, 432, 27
  DB<6> @a = unpack "s*", $b
  DB<7> x @a
0  31
1  1000
2  432
3  27

Familias de Direcciones (Address Families)

El dominio de un socket define la familia de protocolos y esquemas de dirección que serán soportados por el socket.

Ejemplo:

  DB<3> use Socket
  DB<4> @a = (AF_UNIX, AF_INET); print "@a"
1 2

La Función inet_ntoa

La subrutina inet_ntoa toma la dirección empaquetada $packed_address y la convierte en el clásico formato de cuadrupla separada por puntos.

  DB<5> $p = pack 'C4', split /\./, '209.85.135.103'
  DB<6> p join '.', unpack 'C4', $p
209.85.135.103
DB<30> x inet_ntoa($p)
0  '209.85.135.103'

Traducción de IP a Nombre

El programa que sigue realiza la conversión desde una IP a su nombre lógico mediante la función gethostbyaddr.

lhp@nereida:~/Lperl/src/perl_networking/ch3$ name_trans.pl
209.85.135.103
209.85.135.103 => mu-in-f103.google.com
69.147.114.210
69.147.114.210 => f1.www.vip.re3.yahoo.com
147.83.194.21
147.83.194.21 => upc.edu

La Función gethostbyaddr

En un contexto escalar la función gethostbyaddr devuelve el nombre lógico que se corresponden con la dirección IP empaquetada. Si la búsqueda fracasa devuelve undef. Toma dos argumentos: la dirección empaquetada y la familia de direcciones (habitualmente AF_INET).

En un contexto de lista devuelve cinco elementos:

 DB<1> use Socket
 DB<2> x gethostbyaddr(inet_aton('209.85.135.103'), AF_INET)
0  'mu-in-f103.google.com'  # Nombre Canonico
1  ''                       # lista de alias
2  2                        # Tipo AF_INET
3  4                        # Longitud de la dirección
4  'ÑUg'                    # Dirección empaquetada

La función inet_aton toma una dirección IP con notación de punto y la empaqueta.

lhp@nereida:~/Lperl/src/perl_networking/ch3$ cat -n name_trans.pl
 1  #!/usr/bin/perl
 2  use strict;
 3  use Socket;
 4  my $ADDR_PAT = /^\d+\.\d+\.\d+\.\d+$/;
 5
 6  while (<>) {
 7    chomp;
 8    die "$_: Not a valid address" unless /$ADDR_PAT/o;
 9    my $name = gethostbyaddr(inet_aton($_),AF_INET);
10    $name ||= '?';
11    print "$_ => $name\n";
12  }



Subsecciones
Casiano Rodríguez León
Licencia de Creative Commons
Programación Distribuida y Mejora del Rendimiento
por Casiano Rodríguez León is licensed under a Creative Commons Reconocimiento 3.0 Unported License.

Permissions beyond the scope of this license may be available at http://campusvirtual.ull.es/ocw/course/view.php?id=44.
2012-06-19