Exemple #1
0
/*
* ANOTHER ALIAS BY JAY-JAY! This time, it JUST collapses a timer
* He is our miracle. YES, I have done this so many times this is
* copy-paste
*/
void set_delete_flag (rip_route_t * route){

  //int time_left = timerms_left (&route->time);
  //printf ("time_left: %d\n", time_left);
  timerms_reset (&route->time, TIMER_ZERO);
  
}
Exemple #2
0
rip_table_t * convert_message_table (rip_header_ptr pointer, int num_entries){

  rip_table_t * table = rip_table_create ();

  /* 
  * Name of the iface, just for printing @ the table 
  * Recovered from eth.c by an extern directive
  */
  char ifname[IFACE_NAME_LENGTH];
  strcpy( ifname, eth_getname(iface_handler));
  
  int index = 0;

  int i;
  
  for (i=0; i<num_entries; i++){

    rip_route_t * route = rip_route_create 
    (
      pointer->entry [i].ip_addr,
      pointer->entry [i].ip_mask,
      ifname, 
      pointer->entry [i].ip_next,
      pointer->entry [i].metric
      );
   index = rip_route_table_add (table, route);
    
    timerms_reset (&table->routes[index]->time, TIMEOUT);
    
  }
  
  table->num_entries = num_entries;
  
  return table;
}
Exemple #3
0
void add_entries_table (rip_table_t * table, rip_header_ptr pointer, int num_entries){
   

  char ifname[IFACE_NAME_LENGTH];
  strcpy( ifname, eth_getname(iface_handler));

  int index = 0;

  int i;

  for (i=0; i<num_entries; i++){ 

     rip_route_t * route = rip_route_create 
    (
      pointer->entry [i].ip_addr,
      pointer->entry [i].ip_mask,
      ifname, 
      pointer->entry [i].ip_next,
      pointer->entry [i].metric
      );
   index = rip_route_table_add (table, route);
    
    timerms_reset (&table->routes[index]->time, TIMEOUT);
  }
      
}
Exemple #4
0
/*
* In case we receive a better route than one
* of our own, we shall destroy use the one better.
* Otherwise we would be pretty dumb, don't we?
*
* @Params: &table, &route2remove, &route2write,
* AND the index of route2remove
*/
int rip_replace_entry (rip_table_t * table, rip_route_t * route, rip_route_t * route_aux, int index){

  int time_left = timerms_left (&route->time);
  route = rip_route_table_remove (table, index);
  rip_route_free (route);
  index = rip_route_table_add (table, route_aux);
  timerms_reset (&table->routes[index]->time, time_left);
  return index;
  
}
/* int eth_recv 
 * ( eth_iface_t * iface, 
 *   mac_addr_t src, uint16_t type, unsigned char buffer[], long int timeout );
 *
 * DESCRIPCIÓN:
 *   Esta función permite obtener el siguiente paquete recibido por la
 *   interfaz Ethernet indicada. La operación puede esperar indefinidamente o
 *   un tiempo limitando dependiento del parámetro 'timeout'.
 *
 *   Esta función sólo permite recibir paquetes de una única interfaz. Si desea
 *   escuchar varias interfaces Ethernet simultaneamente, utilice la función
 *   'eth_poll()'.
 *
 * PARÁMETROS:
 *    'iface': Manejador de la interfaz Ethernet por la que se desea recibir
 *             un paquete. 
 *             La interfaz debe haber sido inicializada con 'eth_open()'
 *             previamente.
 *      'src': Dirección MAC del equipo que envió la trama Ethernet recibida.
 *             Este es un parámetro de salida. La dirección se copiará en la
 *             memoria indicada, que debe estar reservada previamente.
 *     'type': Valor del campo 'Tipo' de la trama Ethernet que se desea
 *             recibir. 
 *             Las tramas con un valor 'type' diferente serán descartadas.
 *   'buffer': Array donde se almacenarán los datos de la trama recibida.
 *             Deben reservarse al menos 'ETH_MTU' bytes para recibir dichos
 *             datos.
 *  'timeout': Tiempo en milisegundos que debe esperarse a recibir una trama
 *             antes de retornar. Un número negativo indicará que debe
 *             esperarse indefinidamente, mientras que con un '0' la función
 *             retornará inmediatamente, se haya recibido o no una trama.
 *
 * VALOR DEVUELTO:
 *   La longitud en bytes de los datos de la trama recibida, o '0' si no se ha
 *   recibido ninguna trama porque ha expirado el temporizador.
 * 
 * ERRORES:
 *   La función devuelve '-1' si se ha producido algún error. 
 */
int eth_recv(eth_iface_t * iface, mac_addr_t src, uint16_t type, unsigned char buffer[], long int timeout) {
	int payload_len;

	/* Comprobar parámetros */
	if (iface == NULL) {
		fprintf(stderr, "eth_recv(): ERROR: iface == NULL\n");
		return -1;
	}

	/* Inicializar temporizador para mantener timeout si se reciben tramas con
	 tipo incorrecto. */
	timerms_t timer;
	timerms_reset(&timer, timeout);

	int frame_len;
	unsigned char eth_buffer[ETH_FRAME_MAX_SIZE];
	struct eth_frame * eth_frame_ptr = NULL;
	int is_target_type;
	int is_my_mac;
	int is_multicast;

	do {
		long int time_left = timerms_left(&timer);

		/* Recibir trama del interfaz Ethernet y procesar errores */
		frame_len = rawnet_recv(iface->raw_iface, eth_buffer, ETH_FRAME_MAX_SIZE, time_left);
		if (frame_len == -1) {
			fprintf(stderr, "eth_recv(): ERROR en rawnet_recv(): %s\n", rawnet_strerror());
			return -1;
		} else if (frame_len == 0) {

			/* DEBUG */
			if (ETH_LOG >= NORMAL_LOG_LEVEL) {
				printf("eth_recv(): ¡ Timeout !\n");
			}

			return 0;
		}

		/* Comprobar si es la trama que estamos buscando */
		eth_frame_ptr = (struct eth_frame *) eth_buffer;
		is_my_mac = (memcmp(eth_frame_ptr->dest_addr, iface->mac_address, MAC_ADDR_SIZE) == 0);
		is_target_type = (ntohs(eth_frame_ptr->type) == type);

		/* Es el paquete multicast? (comprobamos el bit de la MAC) */
		is_multicast = (eth_frame_ptr->dest_addr[0] && 0x1);

	} while (!((is_my_mac || is_multicast) && is_target_type));

	/* Trama recibida con 'tipo' indicado. Copiar datos y dirección MAC origen */
	memcpy(src, eth_frame_ptr->src_addr, MAC_ADDR_SIZE);
	payload_len = frame_len - ETH_HEADER_SIZE;
	memcpy(buffer, eth_frame_ptr->payload, payload_len);

	/* DEBUG */
	if (ETH_LOG >= VERBOSE_LOG_LEVEL) {
		char mac_addr_str[MAC_ADDR_STR_LENGTH];
		eth_mac_str(src, mac_addr_str);
		char* iface_name = eth_getname(iface);
		printf("eth_recv(type=0x%04x, payload[%d]) < %s/%s\n", type, payload_len, iface_name, mac_addr_str);
		if (ETH_LOG >= DEBUG_LOG_LEVEL) {
			print_pkt((unsigned char *) eth_frame_ptr, frame_len, ETH_HEADER_SIZE);
		}
	}

	return payload_len;
}
Exemple #6
0
void reset_entry_timer (rip_route_t * route){

  timerms_reset(&route->time, TIMEOUT);
  route->garbage_flag = 0;
}
Exemple #7
0
int main(int argc, char * argv[]) {

    system("clear");

    signal(SIGINT, interrupt);

    ipv4_addr_t multiaddress;

    ipv4_str_addr (RIP_MULTICAST_IPv4, multiaddress);

    if(argc == 2) {
        if( !strcmp(argv[1], "--verbose")) {
            is_verbose = 1;
            print_warning("(Debug mode ON) \n");
        }
    }
    else
        printf("(Run with --verbose to print more info)\n");

    bold ("Starting RIP Server... \t\t\t\t\t");
    print_success("[ OK ]\n");

    table = rip_table_create ();
    if (initialize_rip (table, RIP_PORT) == -1) {
        /* Already printed advert inside function */
        return -1;
    }
    int K = rip_route_table_read ( RIP_TABLE_TXT, table );

    /* set inf timer to routes read from file */
    int k;
    for( k = 0; k < K; k++ ) {

        timerms_reset(&table->routes[k]->time, INFINITE_TIMER);
    }

    rip_table_t * table_aux;

    ipv4_addr_t src;
    long int r = random_number(-15, 15)*1000;
//SEND UNSOLICITED RESPONSE MESSAGES EVERY 30 SECONDS +- 15s
    timerms_t update_timer = timer_start ( UPDATE_TIME + r );

//SEND REQUEST TO FILL ROUTE TABLE

    rip_route_table_print ( table );

    for ( ;; ) {

        if (timer_ended (update_timer)) {

            /* Si se ha acabado el update timer */
            send_rip_response (multiaddress, message_ptr, table, RIP_PORT);
            r = random_number(-15, 15)*1000;
            if ( is_verbose ) printf("(update_time set to %ld)\n", r +UPDATE_TIME);
            update_timer = timer_start (UPDATE_TIME + r);

            bold ("\nCurrent table:\n");
            rip_route_table_print ( table );

        }
        int src_port;

        int bytes_received = rip_recv (src, message_ptr, MIN_TIMER, &src_port);

//WE RECEIVE A MESSAGE
        if (bytes_received>0) {

            //WE CONVERT THE MESSAGE TO A ROUTE TABLE FORMAT
            table_aux = convert_message_table (message_ptr, rip_number_entries(bytes_received));

            if ( is_verbose ) {

                print_notice ("\nReceived packet\n");
                print_packet (message_ptr, rip_number_entries(bytes_received));
            }

//IF THE MESSAGE IS A RESPONSE...
            if (message_ptr->command == 2) {

                //VALIDATE (HAY QUE IMPLEMENTARLO)
                //number of entries in the received message
                int num_entries = rip_number_entries (bytes_received);

                int trig_update_flag = 0; //by default, when receiving, do not send update

                //AND THIS IS WHERE THE MAGIC HAPPENS, WE PROCESS THE RESPONSE MESSAGE
                trig_update_flag = compare_tables (table, table_aux, num_entries, src);


                if (trig_update_flag) {

                    send_rip_response (multiaddress, message_ptr, table, RIP_PORT);

                }
                bold ("\nCurrent table:\n");
                rip_route_table_print ( table );
            }

            if (message_ptr->command == 1 &&
                    metric_is_inf(ntohl(message_ptr->entry[0].metric))) {
                //IF REQUEST FOR WHOLE TABLE, RESPOND WITH WHOLE TABLE

                print_warning("Received a request for single entry, sending whole table\n");

                send_rip_response (src, message_ptr, table, src_port);

            }  else if (message_ptr->command == 1) {
//IF REQUEST FOR SPECIFIC ENTRIES, RESPOND WITH SPECIFIC ENTRIES IF FOUND

                print_warning("Received a request for specific entries\n");
                rip_table_t * table_send = table_to_send (table, table_aux);
                send_rip_response (src, message_ptr, table_send, src_port);

            }
        }


        int is_garbage_on = garbage_collector_start (table, garbage_collector_timers);
        int garbage_collected = garbage_collector (table, garbage_collector_timers);

        if (garbage_collected || is_garbage_on) {

            if(garbage_collected)  print_notice("Garbage Collected \n");
            else if(is_garbage_on) print_notice("Garbage countdown ON\n");
            if( is_verbose ) rip_route_table_print(table);
        }
    }

    return 0;
}