/* * 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 rip_route_table_output ( FILE * out, rip_table_t * table, int dontknow) { int err; if (dontknow == 0) { err = fprintf (out, "# SubnetAddr \tSubnetMask \tIface \tNextHop\n"); } else { err = fprintf (out, "# SubnetAddr \tSubnetMask \tIface \tNextHop \tMetric \tTimeout\n"); } if (err < 0) { return -1; } char subnet_str[IPv4_STR_SIZE]; char mask_str[IPv4_STR_SIZE]; char* ifname = NULL; char gw_str[IPv4_STR_SIZE]; int metric; int timeout; int i; for (i=0; i<RIP_ROUTE_TABLE_SIZE; i++) { rip_route_t * route_i = rip_route_table_get(table, i); if (route_i != NULL) { ipv4_addr_str(route_i->ipv4_addr, subnet_str); ipv4_addr_str(route_i->ipv4_mask, mask_str); ifname = route_i->iface; ipv4_addr_str(route_i->ipv4_next, gw_str); metric = route_i->metric; timeout = timerms_left (&route_i->time); /*you like comments don't you? guess this =>*/ if (timeout == -2) timeout = -1; if (metric == 0) { err = fprintf(out, "%-15s\t%-15s\t%s\t%-15s\t%s\n", subnet_str, mask_str, ifname, gw_str, "STATIC"); } else { err = fprintf(out, "%-15s\t%-15s\t%s\t%-15s\t%d\t%d\n", subnet_str, mask_str, ifname, gw_str, metric, timeout); } if (err < 0) { return -1; } } } printf("\n"); return 0; }
/* 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; }
int timer_halfway(rip_route_t * route){ if (timerms_left (&route->time) <= TIMEOUT/2) return 1; else return 0; }