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 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
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 4320033La 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 holaEs 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
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 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'
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
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 }
