Hoy tuve la necesidad de obtener los nombres de host asociados a todas las direcciones IPv4 de una red clase C (ejecutando consultas inversas a los servidores de nombre). Por lo tanto decidí implementar un pequeño script que realice dicha tarea utilizando la shell tcsh, intérprete de comandos por defecto en sistemas FreeBSD. Aunque luego lo traduje a Bash, para compartirlo con aquellos usuarios de GNU/Linux.

El script (el cual decidí llamar "dnsscan") toma como parámetro una cadena elaborada con los tres octetos más significativos de una dirección IPv4 (los cuales identifican a una red clase C). Luego itera desde las direcciones IP 1 a 254 de dicha clase C, consultando los nombres de host a los servidores DNS configurados localmente, mediante el comando host.

Los siguientes pasos explican cómo crear y utilizar el script en un sistema FreeBSD.

Manos a la obra

Crear el script y otorgarle permisos de ejecución:

emi@hal9000:~/scripts % touch dnsscan.sh
emi@hal9000:~/scripts % chmod +x dnsscan.sh

Luego, editar el archivo y agregar el siguiente contenido:

#!/bin/tcsh

if ( $# < 1 ) then
  echo "Usage: $0 A.B.C [DELAY]"
  echo "  A.B.C is a class C network specification"
  echo "  DELAY is seconds between requests (default 0)"
  echo "Examples:"
  echo "  $0 192.168.0 5"
  echo "  $0 10.6.140"
  exit(1)
endif

set NET=$1
set SLEEP=0
if ( $# > 1 ) set SLEEP=$2
set D=1

while ( $D < 255 )
  echo -n "$NET.$D -- "
  host $NET.$D | cut -d' ' -f5
  sleep $SLEEP
  @ D++
end

Tal como se observa, el script incluye una breve ayuda:

emi@hal9000:~/scripts % ./dnsscan.sh
Usage: ./dnsscan.sh A.B.C [DELAY]
  A.B.C is a class C network specification
  DELAY is seconds between requests (default 0)
Examples:
  ./dnsscan.sh 192.168.0 5
  ./dnsscan.sh 10.6.140

Ejemplo de funcionamiento:

emi@hal9000:~/scripts % ./dnsscan.sh 173.194.42 2
173.194.42.1 -- eze03s05-in-f1.1e100.net.
173.194.42.2 -- eze03s05-in-f2.1e100.net.
173.194.42.3 -- eze03s05-in-f3.1e100.net.
173.194.42.4 -- eze03s05-in-f4.1e100.net.

Versión para GNU/Linux

Para no abandonar a los linuxeros decidí implementar el mismo script en Bash:

#!/bin/bash

if [ $# -lt 1 ]; then
  echo "Usage: $0 A.B.C [DELAY]"
  echo "  A.B.C is a class C network specification"
  echo "  DELAY is seconds between requests (default 0)"
  echo "Examples:"
  echo "  $0 192.168.0 5"
  echo "  $0 10.6.140"
  exit 1
fi

NET=$1
SLEEP=0
if [ $# -gt 1 ]; then SLEEP=$2; fi
D=1

while [ $D -lt 255 ]; do
  echo -n "$NET.$D -- "
  host $NET.$D | cut -d' ' -f5
  sleep $SLEEP
  D=$((D+1))
done

Notar la diferencia de sintaxis entre tcsh y Bash, sobre todo en la declaración y seteo de variables, condicionales y ciclos while.

Más allá de estas diferencias, y de que probablemente estemos acostumbrados a utilizar casi exclusivamente Bash, es muy bueno tener conocimientos de uso y desarrollo de scripts bajo diferentes shells. Uno puede decir (y tal vez agregar en el currículum) que posee conocimientos verdaderos de UNIX sólo si ha trabajado alguna vez con csh o tcsh. Si sólo hemos trabajado con Bash, evidentemente nuestra experiencia está limitada a sistemas basados en GNU/Linux.

Aunque no utilicemos otros sistemas más allá de GNU/Linux, es una buena práctica instalar y utilizar shells alternativas como tcsh, ksh o zsh.

Existe una página muy interesante que demuestra cuáles son las principales diferencias entre las shells más utilizadas:

Hyperpolyglot - Unix Shells: Bash, Fish, Ksh, Tcsh, Zsh

Espero que les haya gustado.


Tal vez pueda interesarte


Compartí este artículo