|
@@ -2,6 +2,7 @@
|
2
|
2
|
|
3
|
3
|
![header.png](images/header.png)
|
4
|
4
|
|
|
5
|
+[Verano 2016 - Ive]
|
5
|
6
|
|
6
|
7
|
La *programación orientada a objetos* (object oriented programming, OOP) es un paradigma de programación que promueve el diseño de programas en el que distintos objetos interactúan entre sí para resolver un problema. C++ es uno de los lenguajes de programación que promueve la programación orientada a objetos, permitiendo que los programadores creen sus propias clases desde cero o derivadas de otras clases existentes. Algunos otros lenguajes que promueven OOP son Java, Python, javascript y PHP.
|
7
|
8
|
|
|
@@ -76,7 +77,7 @@ Dentro de la estructura mostrada en la Figura 1 se encuentra:
|
76
|
77
|
3. **Ether Type**: se utiliza para indicar el tipo de de protocolo utilizado en el **payload**. Uno de los **payloads** posibles es un paquete de IP.
|
77
|
78
|
4. **Payload**: contiene un paquete de IP (en realidad puede contener otras cosas, pero para esta experiencia de laboratorio asumiremos que contiene solo IP).
|
78
|
79
|
|
79
|
|
-Dentro del payload, el paquete de IP contiene varios campos, entre ellos:
|
|
80
|
+Dentro del "payload", el paquete de IP contiene varios campos, entre ellos:
|
80
|
81
|
|
81
|
82
|
1. Las direcciones **IP fuente y destino**
|
82
|
83
|
2. Los números de **puerto fuente y destino**
|
|
@@ -95,6 +96,9 @@ En esta experiencia de laboratorio completarás un sniffer de paquetes sencillo
|
95
|
96
|
La aplicación que completarás hoy permite a los usuarios analizar el tráfico de red y monitorear las imágenes que están siendo transferidas a través de tu red.
|
96
|
97
|
|
97
|
98
|
|
|
99
|
+La Figura 2 muestra una foto de la interfaz de la aplicación. Cada fila en la tabla es la información de un paquete capturado. La caja de texto bajo la tabla presenta un resumen del paquete seleccionado en la tabla. La lista en el lado derecho presenta las imágenes que han sido capturadas por el sniffer.
|
|
100
|
+
|
|
101
|
+
|
98
|
102
|
---
|
99
|
103
|
|
100
|
104
|
![figure2.png](images/figure2.png)
|
|
@@ -104,114 +108,94 @@ La aplicación que completarás hoy permite a los usuarios analizar el tráfico
|
104
|
108
|
---
|
105
|
109
|
|
106
|
110
|
|
107
|
|
-
|
108
|
|
-
|
109
|
|
-La Figura 2 muestra una foto de la interfaz de la aplicación. Cada fila en la tabla es la información de un paquete capturado. La caja de texto bajo la tabla presenta un resumen del paquete seleccionado en la tabla. La lista en el lado derecho presenta las imágenes que han sido capturadas por el sniffer.
|
110
|
|
-
|
111
|
|
-
|
112
|
111
|
Para crear un sniffer de paquetes puedes usar la librería de *pcap* que provee una interfaz para accesar la data que está pasando a través de la tarjeta de red de tu computadora. Esta librería contiene una función que devuelve un torrente crudo de los bytes de cada paquete capturado.
|
113
|
112
|
|
114
|
113
|
La tarea del programador del sniffer es decodificar el torrente en crudo a información legible por humanos. Afortunadamente esta no va a ser tu tarea, pero tu puedes aprender a hacerlo, si quieres, leyendo el código fuente de este laboratorio. Tu tarea es seguir los ejercicios de abajo para que puedas proveerle al sniffer los objetos necesarios (Clases) para procesar los paquetes.
|
115
|
114
|
|
116
|
|
-### Ejercicio 1: Familiriarizate con la aplicación
|
|
115
|
+### Ejercicio 1 - Familiarizarte con la aplicación
|
117
|
116
|
|
118
|
117
|
#### Instrucciones
|
119
|
118
|
|
120
|
|
-1. Descarga la carpeta `Classes-SimpleSniffer` a tu computadora escribiendo `git clone http://bitbucket.org/eip-uprrp/classes-simplesniffer` en el terminal.
|
|
119
|
+1. Carga a `QtCreator` el proyecto `SimpleSniffer`. Hay dos maneras de hacer esto:
|
121
|
120
|
|
122
|
|
-2. Para cargar este proyecto necesitas correr `Qt Creator` con privilegios de administrador (root). Para lograr esto, escribe lo siguiente en el terminal:
|
123
|
|
-`sudo qtcreator Documents/eip/classes-simplesniffer/Classes-SimpleSniffer.pro`.
|
|
121
|
+ * Utilizando la máquina virtual: Haz doble “click” en el archivo `SimpleSniffer.pro` que se encuentra en el directorio `/home/eip/labs/classes-simplesniffer` de la máquina virtual.
|
|
122
|
+ * Descargando la carpeta del proyecto de `Bitbucket`: Utiliza un terminal y escribe el commando `git clone http:/bitbucket.org/eip-uprrp/classes-simplesniffer` para descargar la carpeta `classes-simplesniffer` de `Bitbucket`. En esa carpeta, haz doble “click” en el archivo `SimpleSniffer.pro`.
|
124
|
123
|
|
125
|
|
-3. Configura el proyecto. El proyecto consiste de varios archivos. En esta experiencia de laboratorio trabajarás con los archivos `ethernet_hdr.h`, `ethernet_packet.h`, `ethernet_packet.cpp`, `ip_packet.h` y `ip_packet.cpp`.
|
|
124
|
+2. Configura el proyecto. El proyecto consiste de varios archivos. En esta experiencia de laboratorio trabajarás con los archivos `ethernet_hdr.h`, `ethernet_packet.h`, `ethernet_packet.cpp`, `ip_packet.h` y `ip_packet.cpp`.
|
126
|
125
|
|
127
|
|
-### Ejercicio 2: Completar la clase `ethernet_packet`
|
|
126
|
+### Ejercicio 2 - Completar la clase `ethernet_packet`
|
128
|
127
|
|
129
|
|
-Estudia el archivo `ethernet_hdr.h`. Este archivo contiene la siguiente definición de la estructura de datos que representa un encabezado de Ethernet:
|
|
128
|
+1. Estudia el archivo `ethernet_hdr.h`. Este archivo contiene la siguiente definición de la estructura de datos que representa un encabezado de Ethernet:
|
130
|
129
|
|
131
|
|
-```cpp
|
132
|
|
-#define ETHER_ADDR_LEN 6
|
|
130
|
+ #define ETHER_ADDR_LEN 6
|
133
|
131
|
|
134
|
|
-struct sniff_ethernet {
|
|
132
|
+ struct sniff_ethernet {
|
135
|
133
|
u_char ether_dhost[ETHER_ADDR_LEN]; /* direccion destino */
|
136
|
134
|
u_char ether_shost[ETHER_ADDR_LEN]; /* direccion fuente */
|
137
|
135
|
u_short ether_type; /* IP? ARP? RARP? etc */
|
138
|
|
-};
|
139
|
|
-```
|
140
|
|
-
|
141
|
|
-El encabezado de Ethernet de arriba es usado para decodificar la parte Ethernet de los datos crudos en cada paquete. Este se compone de la dirección MAC fuente (`ether_shost`, 6 bytes), la dirección MAC destino (`ether_dhost`, 6 bytes), y el tipo de paquete de Ethernet (`ether_type`, 2 bytes) que es usado para determinar si el paquete es un paquete de IP.
|
142
|
|
-
|
143
|
|
-Como sabes, no es una buena idea enseñar este formato de información a un usuario regular. Tu primer tarea es definir los métodos de la clase de C++ que traducen la información de las direcciones MAC a cadenas de caracteres legibles por humanos.
|
144
|
|
-
|
145
|
|
-El siguiente código es la definición de la clase `ethernet_packet`, que se encuentra en el archivo `ethernet_packet.h`:
|
146
|
|
-
|
147
|
|
-```cpp
|
148
|
|
-class ethernet_packet
|
149
|
|
-{
|
150
|
|
-
|
151
|
|
- sniff_ethernet ethernet ;
|
152
|
|
-
|
153
|
|
- // Devuelve una direccion de 6 bytes MAC en una cadena de caracteres.
|
154
|
|
- string mac2string(u_char []) ;
|
155
|
|
-
|
156
|
|
-public:
|
157
|
|
- ethernet_packet(); // Constructor por defecto
|
158
|
|
-
|
159
|
|
- // Ajusta la variable miembro ether_dhost a los valores
|
160
|
|
- // recibidos en el arreglo
|
161
|
|
- void setEtherDHost(u_char []) ;
|
162
|
|
-
|
163
|
|
- // Ajusta la variable miembro ether_shost a los valores
|
164
|
|
- // recibidos en el arreglo
|
165
|
|
- void setEtherSHost(u_char []) ;
|
166
|
|
-
|
167
|
|
- // Ajusta el ethernet type al valor recibido.
|
168
|
|
- void setEtherType(u_short) ;
|
|
136
|
+ };
|
169
|
137
|
|
170
|
|
- // Devuelve la representación en cadenas de caracteres de las direcciones
|
171
|
|
- // Ethernet
|
172
|
|
- string getEtherDHost() ;
|
173
|
|
- string getEtherSHost() ;
|
|
138
|
+ El encabezado de Ethernet de arriba es usado para decodificar la parte Ethernet de los datos crudos en cada paquete. Este se compone de la dirección MAC fuente (`ether_shost`, 6 bytes), la dirección MAC destino (`ether_dhost`, 6 bytes), y el tipo de paquete de Ethernet (`ether_type`, 2 bytes) que es usado para determinar si el paquete es un paquete de IP.
|
174
|
139
|
|
175
|
|
- // Devuelve el tipo de ethernet.
|
176
|
|
- u_short getEtherType() ;
|
|
140
|
+ Como sabes, no es una buena idea enseñar este formato de información a un usuario regular. Tu primer tarea es definir los métodos de la clase de C++ que traducen la información de las direcciones MAC a cadenas de caracteres legibles por humanos.
|
177
|
141
|
|
178
|
|
-};
|
|
142
|
+2. El siguiente código es la definición de la clase `ethernet_packet`, que se encuentra en el archivo `ethernet_packet.h`:
|
179
|
143
|
|
|
144
|
+ class ethernet_packet
|
|
145
|
+ {
|
|
146
|
+ sniff_ethernet ethernet ;
|
180
|
147
|
|
|
148
|
+ // Devuelve una direccion de 6 bytes MAC en una cadena de caracteres.
|
|
149
|
+ string mac2string(u_char []) ;
|
181
|
150
|
|
182
|
|
-```
|
|
151
|
+ public:
|
|
152
|
+ ethernet_packet(); // Constructor por defecto
|
183
|
153
|
|
184
|
|
-Nota que cada objeto de clase `ethernet_packet` solo tiene el siguiente atributo:
|
185
|
|
-* una estructura tipo `sniff_ethernet` llamada `ethernet`
|
|
154
|
+ // Ajusta la variable miembro ether_dhost a los valores
|
|
155
|
+ // recibidos en el arreglo
|
|
156
|
+ void setEtherDHost(u_char []) ;
|
186
|
157
|
|
187
|
|
-El resto son métodos que actúan como interfaz al atributo:
|
|
158
|
+ // Ajusta la variable miembro ether_shost a los valores
|
|
159
|
+ // recibidos en el arreglo
|
|
160
|
+ void setEtherSHost(u_char []) ;
|
188
|
161
|
|
189
|
|
-* `void setEtherDHost(u_char [])`: es un *setter* para el campo `ether_dhost` del atributo `ethernet`
|
|
162
|
+ // Ajusta el ethernet type al valor recibido.
|
|
163
|
+ void setEtherType(u_short) ;
|
190
|
164
|
|
191
|
|
-* `void setEtherSHost(u_char [])`: es un *setter* para el campo `ether_shost` del atributo `ethernet`
|
|
165
|
+ // Devuelve la representación en cadenas de caracteres de las direcciones
|
|
166
|
+ // Ethernet
|
|
167
|
+ string getEtherDHost() ;
|
|
168
|
+ string getEtherSHost() ;
|
192
|
169
|
|
193
|
|
-* `void setEtherType(u_short)`: es un *setter* para el campo `ether_type` del atributo `ethernet`
|
|
170
|
+ // Devuelve el tipo de ethernet.
|
|
171
|
+ u_short getEtherType() ;
|
|
172
|
+ };
|
194
|
173
|
|
195
|
|
-* `getEtherDHost()` y `getEtherSHost()` son *getters* que devuelven los valores de `ether_dhost` y `ether_shost` en formato legible por humanos, i.e. 6 pares de dígitos hexadecimales (por ejemplo, `e0:f8:47:01:e9:90`).
|
|
174
|
+ Nota que cada objeto de clase `ethernet_packet` solo tiene el siguiente atributo: una estructura tipo `sniff_ethernet` llamada `ethernet`.
|
196
|
175
|
|
197
|
|
-* `getEtherType()` es un *getter* que devuelve el valor de `ether_type` como *unsigned char*.
|
|
176
|
+3. El resto son métodos que actúan como interfaz al atributo:
|
198
|
177
|
|
199
|
|
-* el método privado `string mac2string(u_char [])` recibe un arreglo de seis *unsigned characters* y devuelve el string correspondiente a su representación hexadecimal. Por ejemplo, si recibe `{ 0x8A, 0x11, 0xAB, 0xFF, 0x12, 0x34}` debe devolver el string `"8A:11:AB:FF:12:34"`.
|
|
178
|
+ * `void setEtherDHost(u_char [])`: es un *setter* para el campo `ether_dhost` del atributo `ethernet`
|
|
179
|
+ * `void setEtherSHost(u_char [])`: es un *setter* para el campo `ether_shost` del atributo `ethernet`
|
|
180
|
+ * `void setEtherType(u_short)`: es un *setter* para el campo `ether_type` del atributo `ethernet`
|
|
181
|
+ * `getEtherDHost()` y `getEtherSHost()` son *getters* que devuelven los valores de `ether_dhost` y `ether_shost` en formato legible por humanos, i.e. 6 pares de dígitos hexadecimales (por ejemplo, `e0:f8:47:01:e9:90`).
|
|
182
|
+ * `getEtherType()` es un *getter* que devuelve el valor de `ether_type` como *unsigned char*.
|
|
183
|
+ * el método privado `string mac2string(u_char [])` recibe un arreglo de seis *unsigned characters* y devuelve el string correspondiente a su representación hexadecimal. Por ejemplo, si recibe `{ 0x8A, 0x11, 0xAB, 0xFF, 0x12, 0x34}` debe devolver el string `"8A:11:AB:FF:12:34"`.
|
200
|
184
|
|
201
|
|
-Tu tarea en este ejercicio es implementar las siete funciones listadas arriba en el archivo `ethetnet_packet.cpp`. Los encabezados de algunas de la funciones están provistos en el archivo.
|
|
185
|
+ Tu tarea en este ejercicio es implementar las siete funciones listadas arriba en el archivo `ethetnet_packet.cpp`. Los encabezados de algunas de la funciones están provistos en el archivo.
|
202
|
186
|
|
203
|
|
-### Ejercicio 3: Construir la declaración de `ip_packet`
|
|
187
|
+### Ejercicio 3 - Construir la declaración de `ip_packet`
|
204
|
188
|
|
205
|
|
-Estudia las definiciones de las funciones de la clase `ip_packet` que se encuentra en el archivo `ip_packet.cpp`
|
|
189
|
+1. Estudia las definiciones de las funciones de la clase `ip_packet` que se encuentra en el archivo `ip_packet.cpp`
|
206
|
190
|
|
207
|
|
-Tu tarea es crear la *declaración* de la clase `ip_packet` en el archivo `ip_packet.h` tomando como base los métodos que aparecen en el archivo `ip_packet.cpp`. Los atributos de la clase `ip_packet` deben ser:
|
|
191
|
+2. Tu tarea es crear la *declaración* de la clase `ip_packet` en el archivo `ip_packet.h` tomando como base los métodos que aparecen en el archivo `ip_packet.cpp`. Los atributos de la clase `ip_packet` deben ser:
|
208
|
192
|
|
209
|
|
-* dos objetos de clase `string` para almacenar las direcciones de IP fuente y destino
|
210
|
|
-* una variable de un byte (`char`) para almacenar el tipo de protocolo IP
|
211
|
|
-* dos variables `unsigned short` para almacenar el puerto fuente y destino
|
212
|
|
-* un objeto de clase `string` para almacenar la carga (*payload*) del paquete.
|
|
193
|
+ * dos objetos de clase `string` para almacenar las direcciones de IP fuente y destino
|
|
194
|
+ * una variable de un byte (`char`) para almacenar el tipo de protocolo IP
|
|
195
|
+ * dos variables `unsigned short` para almacenar el puerto fuente y destino
|
|
196
|
+ * un objeto de clase `string` para almacenar la carga (*payload*) del paquete.
|
213
|
197
|
|
214
|
|
-En la declaración de la clase `ip_packet` debes especificar que es una **clase derivada** de la clase `ethernet_packet`.
|
|
198
|
+ En la declaración de la clase `ip_packet` debes especificar que es una **clase derivada** de la clase `ethernet_packet`.
|
215
|
199
|
|
216
|
200
|
---
|
217
|
201
|
|
|
@@ -219,7 +203,7 @@ En la declaración de la clase `ip_packet` debes especificar que es una **clase
|
219
|
203
|
|
220
|
204
|
## Entregas
|
221
|
205
|
|
222
|
|
-1. Utiliza "Entrega" en Moodle para entregar los archivos `ethernet_packet.cpp` y `ip_packet.h` que completaste. Recuerda utilizar buenas prácticas de programación, incluir el nombre de los programadores y documentar tu programa.
|
|
206
|
+Utiliza "Entrega" en Moodle para entregar los archivos `ethernet_packet.cpp` y `ip_packet.h` que completaste. Recuerda utilizar buenas prácticas de programación, incluir el nombre de los programadores y documentar tu programa.
|
223
|
207
|
|
224
|
208
|
---
|
225
|
209
|
|
|
@@ -227,4 +211,4 @@ En la declaración de la clase `ip_packet` debes especificar que es una **clase
|
227
|
211
|
|
228
|
212
|
## Referencias
|
229
|
213
|
|
230
|
|
-[1]http://en.wikipedia.org/wiki/Packet_analyzer
|
|
214
|
+[1] http://en.wikipedia.org/wiki/Packet_analyzer
|