Building Skills

— [ edit | raw ] migrated from node/823

Serie de 3 libros electrónicos sobre programación. El propio autor explica:

How do you build skills in programming? By doing a series of programming exercises that are focused on showing language features one at a time. These books build skills without asking you to assimilate too many technical concepts in a single sitting.

Emulador de Cisco IOS: Dynamips y Dynagen

— [ edit | raw ] migrated from node/821

Esta receta es una introducción al uso de los programas libres dynamips y dynagen que nos permiten emular Cisco IOS. Las posibilidades son infinitas, aqui damos los pasos para poder empezar a trabajar de una forma básica.

Si alguna vez has querido aprender a configurar redes seguramente te has encontrado con un problema para encontrar entornos reales que te permitan aprender los comandos y configuraciones que se necesitan para echar a andar una red real.

Entre los equipos de mayor calidad nos podemos encontrar la gama de routers Cisco. Tener acceso a routers cisco para prácticar es díficil y caro. Afortunadamente existen dos programas que nos pueden simplificar la vida extraordinariamente. Dynamips y Dynagen son dos programas que te permiten configurar una red medianamente compleja y configurar cada uno de los routers presentes en dicha red mediante un emulador que carga una imagen real del sistema operativo de Cisco IOS, es decir, exactamente el mismo sistema operativo que se ejecuta en los equipos reales.

Las ventajas se ven de forma clara, la imagen que carga el dynamips es exactamente la misma que se ejecuta en un router real por lo que el realismo va mucho mas allá del que puedes conseguir con programas como el PacketTracer. PacketTracer es un programa (la licencia no es libre) que te permite modelar redes y configurarlas.

Instalación

Bueno, al tema, los programas dynamips y dynagen son paquetitos debian, asi que, simplemente, apt-get install dynamips y apt-get install dynagen.

En realidad el programa de emulación es dynamips que puede emular los modelos de routers 7200/3600/3725/3745/2600/1700 mientras que dynagen es un front-end basado en texto que te permite crear redes virtuales y trabajar con ellas.

Estos programas han sido creados para prácticar con la configuración de los routers pensando en las certificaciones CCNA/CCNP/CCIE.

Emulando redes virtuales

Una vez instalados, empezar a trabajar con ellos es sumamente sencillo, arrancas dynamips con las opciones que necesites, por ejemplo, en nuestro caso le indicamos que el puerto va a ser el 7200 :

# dynamips -H 7200
Cisco Router Simulation Platform (version 0.2.8-RC2-x86)
Copyright (c) 2005-2007 Christophe Fillot.
Build date: Oct 17 2007 06:50:15
ILT: loaded table "mips64j" from cache.
ILT: loaded table "mips64e" from cache.
ILT: loaded table "ppc32j" from cache.
ILT: loaded table "ppc32e" from cache.
Hypervisor TCP control server started (port 7200).

A ese puerto se conectará dynagen para pasarle los parámetros de configuración de la simulación.

A continuación arrancamos dynagen indicandole el escenario que queremos crear. El paquete debian tiene unos cuantos ejemplos, veamos uno sencillito creado por nosotros:

# Ejemplo

autostart = False

[localhost]

    [[7200]]
        image = /home/pepe/ciscoios/c7200-advsecurityk9-mz.124-15.T1.bin
        npe = npe-400
        ram = 160

    [[ROUTER R1]]
        s1/0 = R2 S1/0
        model = 7200


    [[ROUTER R2]]
        model = 7200

La primera sección [ [ 7200 ] ] nos indica la configuración general de los routers, hay muchos parámetros pero el mas importante y que no puede faltar es la imagen, este parámetro determina la imagen del sistema operativo IOS que debe cargar. Aqui hay un problema, el sistema operativo Cisco IOS es privativo por lo que debemos obtener una imagen de algún sitio autorizado. Y aviso a navegantes YO NO PUEDO DISTRIBUIR CISCO IOS por lo que tendrás que conseguirla por tus propios medios. (ACTUALIZACIÓN: Parece que hay gente que puede distribuirlas, mira al final de esta receta).

A continuación se definen dos routers [[ROUTER R1]] y [[ROUTER R2]] ambos con
el modelo 7200 (que debe coincidir con la imagen de sistema operativo que cargamos), el atributo model proporciona el modelo de router (7200 en nuestro caso) mientras que tambien debemos especificar las conexiones:

        s1/0 = R2 S1/0

Esta sentencia nos indica que la linea serial del router R1 la conectamos a la linea serial S1/0 del router R2.

Si arrancamos el dynagen pasándole como argumento este archivo, que llamaremos simple.net, obtenemos una consola de texto:

$ dynagen simple.net
Reading configuration file...
Network successfully loaded
Dynagen management console for Dynamips
Copyright (c) 2005-2007 Greg Anuzelli
=>

La cantidad de opciones y configuraciones posibles son infinitas, lo mas básico para empezar a trabajar es observar los dispositivos que existen en la red con el comando list:

=> list
Name       Type       State      Server          Console
R1         7200       stopped    localhost:7200  2000
R2         7200       stopped    localhost:7200  2001
=>

Arrancar los routers:

=> start /all
Warining: Starting R1 with no idle-pc value
100-VM 'R1' started
Warining: Starting R2 with no idle-pc value
100-VM 'R2' started

y obtener una consola para trabajar con los distintos routers:

=> console /all
=>

Al ejecutar este comando deben aparecer dos consolas, cada una de ellas representa un router y puedes ver como carga la imagen del sistema operativo y podremos empezar a trabajar con comandos reales.

Para terminar varios consejos, dynamips y dynagen consumen muchos recursos, si quieres optimizar y que no consuma tanto mira la opción idle-pc.

Entre las características de dynagen te permite capturar paquetes en distintas interfaces de tu red virtual en el formato .cap que con posterioridad puedes visualizar con programas como wireshark.

Si quieres echarle un vistazo a las posibilidades de estos programas:

http://www.dynagen.org/tutorial.htm

y David se ha encontrado una página con imágenes de Cisco IOS para bajárselas aquí

GNU Emacs: Construir un «major mode» paso a paso

— [ edit | raw ] migrated from node/815
Esta receta explica cómo hacer un _major mode_ para facilitar la edición de un lenguaje de programación, incluyendo resalte de sintaxis e indentado automático.

Analizador léxico, sintáctico y semántico con JFlex y CUP

— [ edit | raw ] migrated from node/819
La siguiente receta explica con un ejemplo como construir un analizador léxico con JFlex y un analizador sintáctico y semántico con CUP (obviamente para Java). Además, muestra el uso de producciones de error.

Requisitos

  • jflex - analizador léxico para Java
  • cup - analizador sintáctico/semántico LALR para Java

Construcción

El ejemplo consiste en un conversor de unidades métricas. Admitiría textos de entradas del siguiente tipo: Entrada.txt
Km 1 mm;
dm 3 dm;
Hm 393 m;
Dm 54 cm, mm 3429 dm;
Km 23 Dm;
dm 322 cm, Hm 0923 mm;
y devuelve en consola:
1 Km  son 1000000 mm;
3 dm son 3 dm;
393 Hm son 39300 m;
...
 
Un archivo flex tiene la siguiente estructura (cada sección se separa mediante %%) :
  1. Código de usuario
  2. Opciones y declaraciones
  3. Reglas léxicas
Conversor.lex
//* ------------Sección codigo-usuario -------- */
import java_cup.runtime.*;
%%
/*- Sección de opciones y declaraciones -*/
/*-OPCIONES --*/
/* Nombre de la clase generada para el analizador lexico */
%class conversor
/* Indicar funcionamiento autonomo*/
%standalone
%8bit
/* Acceso a la columna y fila actual de analisis CUP */
%line
%column
/* Habilitar la compatibilidad con el interfaz CUP para el generador sintactico*/
%cup
/*-- DECLARACIONES --*/
%{/*Crear un nuevo objeto java_cup.runtime.Symbol con información sobre el token actual sin valor*/

  private Symbol symbol(int type){
    return new Symbol(type,yyline,yycolumn);
  }
/* Crear un nuevo objeto java_cup.runtime.Symbol con información sobre el token actual con valor*/
  private Symbol symbol(int type,Object value){
    return new Symbol(type,yyline,yycolumn,value);
  }
%}
/*-- MACRO DECLARACIONES --*/
LineTerminator = \r|\n|\r\n
WhiteSpace     = {LineTerminator} | [ \t\f]
//finConversion	= [,;]
num_int = [0-9]+
%%
/*-------- Sección de reglas lexicas ------ */
<YYINITIAL> {
//{finConversion}{ return symbol.FCONVERSION}

","	{ return symbol(sym.COMA);}
";"	{ return  symbol(sym.PUNTOCOMA);}
"mm"	{ return  symbol(sym.MM); }
"cm"	{ return  symbol(sym.CM); }
"dm"	{ return  symbol(sym.DCM); }
"m"	{ return  symbol(sym.M); }
"Dm"	{ return  symbol(sym.DCAM); }
"Hm"	{ return  symbol(sym.HM); }
"Km"	{ return  symbol(sym.KM); }
{num_int}	{ return symbol(sym.NUMBER, new Integer(yytext())); }

{WhiteSpace}	{ }
. {System.out.println("token ilegal <" + yytext()+ ">  linea: " + (yyline+1) + " columna: " + (yycolumn+1));}
}
En cuanto a un fichero CUP se pueden diferenciar cinco partes:
  1. Especificaciones de “package” e “imports”.
  2. Componentes de código de usuario.
  3. Lista de símbolos de la gramática(terminales­no terminales).
  4. Declaraciones de precedencia.
  5. Especificación de la gramática.
Conversor.cup
/*­­­­Sección de declaraciones package e imports­­­­­­­­­*/
import java_cup.runtime.*;
/*­­­­ Sección componentes de código de usuario ­­­­*/
parser code {:
    public void report_error(String message, Object info) {
       	StringBuffer m = new StringBuffer("Error");
		System.out.println("Mensaje: "+message);
		System.out.println("info: "+info.toString());
		if(info instanceof java_cup.runtime.Symbol) {
			java_cup.runtime.Symbol s=((java_cup.runtime.Symbol)info);
			/* Comprueba si el numero de línea es mayor o igual que cero */
			if(s.left >= 0) {
				m.append(" en linea "+(s.left+1));
				/*Comprueba si el numero de columna es mayoro igual que cero */
				if (s.right >= 0)
					m.append(", y columna "+(s.right+1));
			}
		}
		m.append(" : "+message);
		System.err.println(m);
    }
    public void report_fatal_error(String message, Object info) {
       	report_error(message, info);
		System.exit(1);
    }

public void conversion(String a, String b, int n){

	int c=0,d=0;
	System.out.print(n+" ");
	if (a=="Km"){ c=6; System.out.print("Km"); }
	else if (a=="Hm"){ c=5; System.out.print("Hm"); }
	else if (a=="Dm"){ c=4; System.out.print("Dm"); }
	else if (a=="m"){ c=3; System.out.print("m"); }
	else if (a=="dm"){ c=2; System.out.print("dm"); }
	else if (a=="cm"){ c=1; System.out.print("cm"); }
	else if (a=="mm"){ c=0; System.out.print("mm"); }

	if (b=="Km") d=6;
	else if (b=="Hm") d=5;
	else if (b=="Dm") d=4;
	else if (b=="m") d=3;
	else if (b=="dm") d=2;
	else if (b=="cm") d=1;
	else if (b=="mm") d=0;

	System.out.print(" son "+n*Math.pow(10,c-d)+" ");

}

:};
/*­­­ Declaración de la lista de símbolos de la gramática ­­­­­*/

/* Produciones de flujo normal */
terminal COMA, PUNTOCOMA, MM, DCM, CM, M, DCAM, HM, KM;
terminal Integer NUMBER;
non terminal Object programa, linea, expresiones, medida;

/* ­­­­­­­­­­­­­­ Declaración de la gramática  ­­­­­­­­­­­ */
programa ::= programa linea | linea;

linea ::= error NUMBER medida PUNTOCOMA {: parser.report_error("revise la sintaxis",null); :} |
	medida:m1 NUMBER:n medida:m2 PUNTOCOMA {: parser.conversion(m1.toString(),m2.toString(),n.intValue());
 	System.out.println(m2); :} |
	expresiones medida:m1 NUMBER:n medida:m2 PUNTOCOMA
 	{: parser.conversion(m1.toString(),m2.toString(),n.intValue());
	System.out.println(m2); :} ;

expresiones ::= expresiones medida:m1 NUMBER:n medida:m2 COMA
	{: parser.conversion(m1.toString(),m2.toString(),n.intValue());
	System.out.println(m2); :} |
	medida:m1 NUMBER:n medida:m2 COMA {: parser.conversion(m1.toString(),m2.toString(),n.intValue());
 	System.out.println(m2); :} |
	error NUMBER medida COMA {: parser.report_error("revise las medidas en mayusculas",null); :};

medida ::= KM {: RESULT="Km"; :} | HM {: RESULT="Hm"; :} | DCAM {: RESULT="Dm"; :} |
	M {: RESULT="m"; :} | DCM {: RESULT="dm"; :} |
	CM {: RESULT="cm"; :} | MM {: RESULT="mm"; :};
Necesitas un fichero que cree un objeto parser y comience el análisis. Main.java
import java_cup.runtime.Symbol;
import java.io.*;
class Main {
    static boolean do_debug_parse = false;
    static public void main(String[] args) throws java.io.IOException {
		parser parser_obj = new parser(new conversor(new FileReader(args[0])));
		Symbol parse_tree = null;
		try {
			if (do_debug_parse)
				 parse_tree = parser_obj.debug_parse();
			else parse_tree = parser_obj.parse();
			System.out.println("Entrada correcta");
		} catch (Exception e) {
			System.out.println("Horror");
		}

    }
}
Makefile
all: java
	javac *.java

java:
	jflex *.lex
	cup *.cup

clean:
	$(RM) *.class
	$(RM) parser.java sym.java
	$(RM) *~

Referencias

JFlex CUP

Creación de un parser con flex y bison en C++

— [ edit | raw ] migrated from node/818
La siguiente receta explica como construir un analizador léxico con Flex y un analizador sintáctico con Bison, utilizando C++. Además, incluye un pequeño Makefile para el enlazado de todos los archivos y un ejemplo mínimo de uso.

Entrevista a Ana María Méndez (APEMIT)

— [ edit | raw ] migrated from node/816
Hola... hoy me he encontrado por ahí una entrevista muy interesante sobre una buena mujer, Ana María Méndez, que por lo visto tenía una tiendecilla de informática y la SGAE la tomó con ella (como con muchas otras). La mujer decidió plantar cara y acabó fundando APEMIT. La entrevista es un poco larga pero tiene cosas muy muy interesantes, de las cuales sólo pondré lo siguiente (que curiosamente no tiene que ver con la SGAE):

Conectar a Internet por medio de un móvil 3G EDITADO

— [ edit | raw ] migrated from node/817
Cómo conectar a Internet por medio de un teléfono 3G en un sistema GNU/Linux

Introducción

Explicaré como he conseguido conectarme a internet desde mi Debian. En concreto yo me he conectado a través del operador Simyo, que ofrece una tarifa de internet móvil de lo mas competitivo que he visto (perdón si ha parecido que hago publicidad, pero me ha parecido un "chollo" y tengo que compartilo con vosotros :-D).

Ingredientes

Ésto es lo que yo he utilizado:
  • Teléfono libre con tecnología 3G (yo en concreto he utilizado un Nokia 6630)
  • Una tarjeta Simyo
  • wvdial
También supondremos que tenemos tanto una conexión bluetooth establecida con nuestro teléfono en /dev/rfcomm0 como una conexión USB en /dev/ttyACM0.

Configuración de wvdial

La conexión la estableceremos a través de wvdial. Para ello deberemos crear un archivo llamado .wvdialrc con el siguiente contenido:
[Dialer SimyoUSB]
Modem = /dev/ttyACM0
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2
Init3 = AT+CGDCONT=1,"IP","gprs-service.com"
Phone = *99***1#
Username = ''
Password = ''

[Dialer SimyoBT]
Modem = /dev/rfcomm0
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2
Init3 = AT+CGDCONT=1,"IP","gprs-service.com"
Phone = *99***1#
Username = ''
Password = ''

Conexión

Una vez hecho lo anterior, abrir una conexión es tan fácil como:
javieralso@avalon:~$ sudo wvdial SimyoUSB
Si queremos conectarnos a través del cable USB a nuestro móvil y
javieralso@avalon:~$ sudo wvdial SimyoBT
si queremos conectarnos a través del Bluetooth.

Referencias

Pues cerré el navegador sin darme cuenta de anotar todas las páginas en las que había buscado. Ya lo vuelvo a buscar en otro momento :-P

Parted y Python: pyparted

— [ edit | raw ] migrated from node/812
Supongo que muchos de vosotros conoceréis libparted, la librería que hay debajo de los programas de particionado típicos de GNU. Muchos de vosotros conocéis también Python, si juntamos estas dos cosas tenemos que hacer programitas que manejen el particionado del disco va a estar al alcance de cualquiera. Llegados a este punto, no sobra decir que: NO me responsabilizo de los daños que pueda causar el uso de esta receta, yo lo he probado con un disco flash y me ha funcionado sin problemas. Quien quiera garantías... que las pague :P.

New Debian Developer

— [ edit | raw ] migrated from node/814

Enhorabuena! Supongo que se celebrará como merece, no?

Nuevo sistema antipiratería de Vista SP1: dar la brasa!

— [ edit | raw ] migrated from node/813
Leemos en engadget que el nuevo sistema antipiratería del Vista SP1 NO va a inutilizar las copias piratas que detecte, en lugar de eso sólo mostrará mensajes una y otra vez por pantalla dando el coñazo. Por lo visto que el motivo es que "han tomado esta decisión tomando en consideración las opiniones de los usuarios" según Alex Kochis, jefe del producto WGA (protección anti-piratería)... o lo que viene a ser lo mismo: los usuarios de Windows Vista son unos piratas.