Logo Studenta

arpt

Esta es una vista previa del archivo. Inicie sesión para ver el archivo original

/***************************************************************************
 * arpt.c
 *
 * Programa principal para probar ARP en las practicas de 
 * Arquitectura de Redes de Comunicaciones 2 de la EPS-UAM
 *
 * Autores: Manuel Freire, Jose Hernandez, Javier Ramos
 *
 * (C) 2006-12 EPS-UAM 
 ***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include "nivel1.h"
#include "rc_funcs.h"
#include "arp.h"
#define MAX_LINEA 256 
 
/****************************************************************************
 * Procesa tramas Ethernet entrantes desde el nivel1
 * Copia la trama y, si es procesable, la procesa
 *
 * entra:
 * tamano - en bytes de toda la trama, incluyendo cabeceras ethernet
 * trama - los bytes de la trama
 * sale:
 * 0 si todo bien, -1 si error en el procesamiento
 ****************************************************************************/
#ifdef _ETHD_VERSION_4_1_0
int gestiona_trama_ethernet(int tamano, const BYTE *trama) {
#else
int gestiona_trama_ethernet(int tamano, const BYTE *trama,struct timeval *tv) {
#endif
 BYTE buffer[ETH_FRAME_MAX];
 
 /*
 * 'recibe' la trama oficialmente de nivel1, realizando una copia.
 * NOTA: nivel1 nunca llama a esta funcion de forma reentrante, porque 
 * gestiona la recepcion de tramas segun llegan en un unico hilo
 */
	
	
#ifdef _ETHD_VERSION_4_1_0
 if (RecibirTramaNivel1(buffer) != tamano) {
#else
 if (RecibirTramaNivel1(buffer,NULL) != tamano) {
#endif
 fprintf(stderr, "Error: fallo en nivel1 recibiendo trama\n");
 return -1;
 } 
 
 // comprueba si es una trama ARP, y en caso afirmativo, la procesa
 if (tamano == ETH_FRAME_MIN && 
 memcmp(ethertype_arp, buffer+ETH_ALEN+ETH_ALEN, ETH_TLEN) == 0) { 
 
 arp_inicializa();
 arp_procesa_trama(tamano, buffer, buffer+ETH_ALEN);
 }
 
 return 0;
}
/***************************************************************************
 * "main"
 ***************************************************************************/
int main(int argc, char **argv)
{
 char buffer[MAX_LINEA];
 BYTE dir_ip[IP_ALEN];
 BYTE dir_eth[ETH_ALEN];
 int debug = 0;
 int fin_solicitado = 0;
 int rc;
 
 char *ayuda =
 "Uso: arpt [<nivel_trazas>]\n"
 " <nivel_trazas> - 0 = sin trazas, 3 = maximo detalle\n";
 
 char *teclas = 
 "Usa:\n"
 " 'a' - enviar una peticion\n"
 " 'c' - mostrar la tabla ARP\n"
 " 'q' - salir\n"; 
 
 // trazas
 if (argc > 1) {
 debug = atoi(argv[1]);
 if (argv[1][0] < '0' || argv[1][0] > '9' || debug < 0 || debug > 3) {
 fprintf(stderr, ayuda);
 }
 }
 ActivarTrazas(debug, "stdout");
 // inicia el nivel1; no usa 'timeout' para la recepcion
 if (IniciarNivel1(1, ethertype_arp, gestiona_trama_ethernet, 0) != ETH_OK) {
 fprintf(stderr, "Error en IniciarNivel1\n");
 return -1;
 }
 if (arp_inicializa() != 0) {
 fprintf(stderr, "Error en arp_inicializa\n");
 FinalizarNivel1();
 return -1;
 } 
 // bucle principal
 printf("ARP-T iniciado; usa 'h' para ver la ayuda.\n");
 while ( ! fin_solicitado) {
 if (fgets(buffer, MAX_LINEA, stdin) == NULL) {
 fin_solicitado = 1;
 }
 else {
 switch (buffer[0]) {
 case 'a': case 'A':
 if (lee_cadena_ip(buffer+2, dir_ip) != -1) {
 rc = arp_solicita_direccion(dir_ip, dir_eth);
 if (rc == -1) {
 printf("Direccion Eth. no encontrada.\n");
 }
 else {
 printf("Direccion Eth. encontrada: "
 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", 
 dir_eth[0], dir_eth[1], dir_eth[2],
 dir_eth[3], dir_eth[4], dir_eth[5]);
 }
 }
 else {
 printf("Dir. IP mal escrita; vuelve a intentarlo.\n");
 }
 break;
 case 'c': case 'C':
 arp_muestra_cache();
 break;
 case 'q': case 'Q': case -1:
 fin_solicitado = 1; 
 break;
 case 'h': case 'H':
 printf(teclas);
 break;
 case '\n':
 break;
 default:
 printf("No entiendo '%s'. %s", buffer, teclas);
 break;
 }
 }
 }
 // salida limpia (Ctrl+C tambien funciona, pero esto es mas bonito)
 if (FinalizarNivel1() != ETH_OK) {
 printf("Error en FinalizarNivel1, rc = %d \n",rc);
 return -1;
 }
 return 0;
}

Otros materiales