int main(int argc, char *argv[]) { /* Argument processing and help */ if (argc != 2) { printf("Use: %s <ip>\n", argv[0]); return -1; } /*---------------------------Preparing Stuff------------------------------*/ /*RIP packet declaration*/ rip_packet rip_request; int rip_request_size = size_of_packet_for_rip_entries(1); /*One request*/ /*RIP packet filling*/ rip_request.command = RIP_REQUEST; rip_request.version = RIP_VERSION; rip_request.zero = 0; printf("RIP Entry has a size of %d\n", (int)sizeof(rip_entry)); rip_request.rip_entries[0].metric = htonl(16); rip_request.rip_entries[0].family_id = 0x0000; print_rip_packet(&rip_request, rip_request_size); // memset(&(rip_request.rip_entries[0]), 0, 20); // rip_request.rip_entries[0].route_tag=0x2222; // memcpy(rip_request.rip_entries[0].ip, ip_to, 4); // memcpy(rip_request.rip_entries[0].mask, ip_to, 4); // memcpy(rip_request.rip_entries[0].nexthop, ip_to,4); /*---------------------------Sending Stuff--------------------------------*/ /*Preparing UDP frame*/ ipv4_addr_t ip_to; ipv4_str_addr(argv[1], ip_to); /*Open tables and whatnot*/ ipv4_open("ipv4_config.txt", "ipv4_route_table.txt"); /*SEEEEEEEEND*/ printf("[RIP] Enviando request RIP..\n"); udp_send(ip_to, RIP_PORT, 2000, (unsigned char*) &rip_request, rip_request_size); /*---------------------------Receiving Stuff------------------------------*/ /*Prepare a buffer and source IP for incoming UDP frame*/ unsigned char r_buffer[UDP_MAX_SIZE]; unsigned short int src_port; ipv4_addr_t source_ip; /*Receive*/ int bsize = udp_receive(source_ip, &src_port, 2000, r_buffer, INFINITE_TIMEOUT); /*print what we just received (a RIP packet supposedly)*/ print_rip_packet((rip_packet*) r_buffer, bsize); return 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; }
int rip_route_table_read ( char * filename, rip_table_t * table ) { int read_routes = 0; FILE * routes_file = fopen(filename, "r"); if (routes_file == NULL) { fprintf(stderr, "Error opening input IPv4 Routes file \"%s\": %s.\n", filename, strerror(errno)); return -1; } int linenum = 0; char line_buf[1024]; char subnet_str[256]; char mask_str[256]; char iface_name[256]; char gw_str[256]; char metric_str[256]; char timeout_str[256]; int err = 0; while ((! feof(routes_file)) && (err==0)) { linenum++; /* Read next line of file */ char* line = fgets(line_buf, 1024, routes_file); if (line == NULL) { break; } /* If this line is empty or a comment, just ignore it */ if ((line_buf[0] == '\n') || (line_buf[0] == '#')) { err = 0; continue; } /* Parse line: Format "<subnet> <mask> <iface> <gw>\n" */ err = sscanf(line, "%s %s %s %s %s %s\n", subnet_str, mask_str, iface_name, gw_str, metric_str, timeout_str); if (err != 6) { fprintf(stderr, "%s:%d: Invalid IPv4 Route format: \"%s\" (%d items)\n", filename, linenum, line, err); fprintf(stderr, "%s:%d: Format must be: <subnet> <mask> <iface> <gw>\n", filename, linenum); err = -1; } else { /* Parse IPv4 route subnet address */ ipv4_addr_t subnet; err = ipv4_str_addr(subnet_str, subnet); if (err == -1) { fprintf(stderr, "%s:%d: Invalid <subnet> value: \"%s\"\n", filename, linenum, subnet_str); break; } /* Parse IPv4 route subnet mask */ ipv4_addr_t mask; err = ipv4_str_addr(mask_str, mask); if (err == -1) { fprintf(stderr, "%s:%d: Invalid <mask> value: \"%s\"\n", filename, linenum, mask_str); break; } /* Parse IPv4 route gateway */ ipv4_addr_t gateway; err = ipv4_str_addr(gw_str, gateway); if (err == -1) { fprintf(stderr, "%s:%d: Invalid <gw> value: \"%s\"\n", filename, linenum, gw_str); break; } int metric = atoi (metric_str); //int timeout = atoi (timeout_str); /* Create new route & add it to Route Table */ rip_route_t * new_route = rip_route_create(subnet, mask, iface_name, gateway, ntohl(metric)); if (table != NULL) { err = rip_route_table_add(table, new_route); if (err >= 0) { err = 0; read_routes++; } } } } /* while() */ if (err == -1) { read_routes = -1; } /* Close IP Route Table file */ fclose(routes_file); table->num_entries = read_routes; return read_routes; }
int main (int argc, char * argv[]){ printf ("\n--------------X ROUTING CONFIG--------------\n\n"); printf ("COMMAND LIST: command_list\n"); printf ("MANUAL: man <command>\n"); printf ("EXIT: exit\n"); printf ("\n"); char user_input [USER_INPUT], *result;; char user_command [40]; char arg1 [30]; char arg2 [30]; char arg3 [30]; char arg4 [30]; char arg5 [30]; char aux_buffer[200]; int p = 0; while (p == 0){ printf ("> "); result = fgets (user_input, USER_INPUT, stdin); int j; for (j=0; j<200; j++){ if (user_input [j] == ' '){ aux_buffer[j] = '|'; ++j;} else{ if(user_input [j] == '\n'){aux_buffer[j] ='\0'; break;}} aux_buffer[j] = user_input [j]; } int i; int stream_index; int end_of_stream = 0; int arg_num = 0; for (i=0; i<40; i++){ if (aux_buffer[i] == '|' || aux_buffer[i] == '\0'){ if (aux_buffer[i] == '|'){ stream_index = i+1; arg_num++; user_command [i] = '\0';} else {aux_buffer[i] = '\0'; end_of_stream = 1; arg_num++; user_command [i] = '\0';} break; } user_command [i] = aux_buffer[i]; } int command_number = 0; if (strcmp (user_command, "") == 0) command_number = 69; /*if (command_number != 69){ printf ("\n> USER COMMAND: >%s<\n", user_command);}*/ if (strcmp (user_command, "route_create") == 0) command_number = 1; if (strcmp (user_command, "route_lookup") == 0) command_number = 2; if (strcmp (user_command, "route_print") == 0) command_number = 3; if (strcmp (user_command, "route_table_remove") == 0) command_number = 4; if (strcmp (user_command, "route_table_find") == 0) command_number = 5; if (strcmp (user_command, "route_table_lookup") == 0) command_number = 6; if (strcmp (user_command, "route_table_read") == 0) command_number = 7; if (strcmp (user_command, "route_table_write") == 0) command_number = 8; if (strcmp (user_command, "route_table_print") == 0) command_number = 9; if (strcmp (user_command, "man") == 0) command_number = 10; if (strcmp (user_command, "command_list") == 0) command_number = 11; if (strcmp (user_command, "exit") == 0) command_number = 12; if (strcmp (user_command, "clear") == 0) command_number = 13; if (command_number != 69)//{ if (command_number == 0) printf ("> COMMAND NOT FOUND\n"); //else printf ("> COMMAND NUMBER: >%d<\n\n", command_number);} int end_loop = 0; int k = 0; if (end_of_stream == 0){ arg_num = 2; for (i=stream_index; i<170; i++){ switch (arg_num){ case 2: arg1 [k] = aux_buffer[i]; ++k; if (aux_buffer[i+1] == '|'){++arg_num; ++i; arg1 [k] ='\0'; k=0;} else{if (aux_buffer[i+1] == '\0'){end_loop = 1; arg1 [k] ='\0';}} break; case 3: arg2 [k] = aux_buffer[i]; ++k; if (aux_buffer[i+1] == '|'){++arg_num; ++i; arg2 [k] ='\0'; k=0;} else{if (aux_buffer[i+1] == '\0'){end_loop = 1; arg2 [k] ='\0';}} break; case 4: arg3 [k] = aux_buffer[i]; ++k; if (aux_buffer[i+1] == '|'){++arg_num; ++i; arg3 [k] ='\0'; k=0;} else{if (aux_buffer[i+1] == '\0'){end_loop = 1; arg3 [k] ='\0';}} break; case 5: arg4 [k] = aux_buffer[i]; ++k; if (aux_buffer[i+1] == '|'){++arg_num; ++i; arg4 [k] ='\0'; k=0;} else{if (aux_buffer[i+1] == '\0'){end_loop = 1; arg4 [k] ='\0';}} break; case 6: arg5 [k] = aux_buffer[i]; ++k; if (aux_buffer[i+1] == '|'){++arg_num; ++i; arg5 [k] ='\0'; k=0;} else{if (aux_buffer[i+1] == '\0'){end_loop = 1; arg5 [k] ='\0';}} break; } if (end_loop == 1) break; } } int arg_num_required; int exit_flag = 0; ipv4_addr_t ip_addr; ipv4_addr_t ip_mask; ipv4_addr_t ip_gw; int index; unsigned int adist; if (ipv4_route_table_aux == NULL) ipv4_route_table_aux = ipv4_route_table_create (); switch (command_number){ case 1: arg_num_required = 6; if (arg_num != arg_num_required){ printf ("> usage: route_create <ip_addr> <ip_mask> <iface> <gw> <adist>\n"); break;} ipv4_str_addr (arg1, ip_addr); ipv4_str_addr (arg2, ip_mask); ipv4_str_addr (arg4, ip_gw); adist = (unsigned int) atoi (arg5); ipv4_route_t * ipv4_route_new; ipv4_route_new = ipv4_route_create (ip_addr, ip_mask, arg3, ip_gw, adist); ipv4_route_table_add (ipv4_route_table_aux, ipv4_route_new); break; case 2: break; case 3: arg_num_required = 3; if (arg_num != arg_num_required){ printf ("> usage: route_print <ip_addr> <ip_mask>\n"); break;} ipv4_str_addr (arg1, ip_addr); ipv4_str_addr (arg2, ip_mask); index = ipv4_route_table_find (ipv4_route_table_aux, ip_addr, ip_mask); ipv4_route_aux = ipv4_route_table_get (ipv4_route_table_aux, index); ipv4_route_print (ipv4_route_aux); printf ("\n\n"); break; case 4: arg_num_required = 3; if (arg_num != arg_num_required){ printf ("> usage: route_table_remove <ip_addr> <ip_mask>\n"); break;} index = ipv4_route_table_find (ipv4_route_table_aux, ip_addr, ip_mask); ipv4_route_aux = ipv4_route_table_remove (ipv4_route_table_aux, index); ipv4_route_free (ipv4_route_aux); break; case 5: arg_num_required = 3; if (arg_num != arg_num_required){ printf ("> usage: route_table_find <ip_addr> <ip_mask>\n"); break;} ipv4_str_addr (arg1, ip_addr); ipv4_str_addr (arg2, ip_mask); index = ipv4_route_table_find (ipv4_route_table_aux, ip_addr, ip_mask); printf ("INDEX FOR SUBNET %s WITH MASK %s: %d\n\n", arg1, arg2, index); break; case 6: ipv4_route_aux = NULL; arg_num_required = 2; if (arg_num != arg_num_required){ printf ("> usage: route_table_lookup <ip_addr>\n"); break;} ipv4_str_addr (arg1, ip_addr); ipv4_route_aux = ipv4_route_table_lookup (ipv4_route_table_aux, ip_addr); if (ipv4_route_aux != NULL){ ipv4_route_print (ipv4_route_aux); printf ("\n");} else printf ("No route available\n"); break; case 7: arg_num_required = 2; if (arg_num != arg_num_required){ printf ("> usage: route_table_read <filename>\n"); break;} ipv4_route_table_read (arg1, ipv4_route_table_aux); break; case 8: arg_num_required = 2; if (arg_num != arg_num_required){ printf ("> usage: route_table_write <filename>\n"); break;} ipv4_route_table_write (ipv4_route_table_aux, arg1); break; case 9: arg_num_required = 1; if (arg_num != arg_num_required){ printf ("> usage: route_table_print\n"); break;} printf ("\n"); ipv4_route_table_print (ipv4_route_table_aux); printf ("\n"); break; case 10: arg_num_required = 2; if (arg_num != arg_num_required){ printf ("> usage: man <command>\n"); break;} int man_number; if (strcmp (arg1, "route_create") == 0) man_number = 1; if (strcmp (arg1, "route_lookup") == 0) man_number = 2; if (strcmp (arg1, "route_print") == 0) man_number = 3; if (strcmp (arg1, "route_table_remove") == 0) man_number = 4; if (strcmp (arg1, "route_table_find") == 0) man_number = 5; if (strcmp (arg1, "route_table_lookup") == 0) man_number = 6; if (strcmp (arg1, "route_table_read") == 0) man_number = 7; if (strcmp (arg1, "route_table_write") == 0) man_number = 8; if (strcmp (arg1, "route_table_print") == 0) man_number = 9; if (strcmp (arg1, "man") == 0) man_number = 10; if (strcmp (arg1, "command_list") == 0) man_number = 11; if (strcmp (arg1, "exit") == 0) man_number = 12; if (strcmp (arg1, "clear") == 0) command_number = 13; printf ("\n"); switch (man_number){ case 1: printf ("route_create <ip_addr> <ip_mask> <iface> <gw> <adist>\n\n"); printf ("This command creates an IPv4 route\n\n"); printf ("<ip_addr>\t\tIPv4 subnet destination address\n"); printf ("<ip_mask>\t\tDestination subnet mask\n"); printf ("<iface>\t\t\tInterface name\n"); printf ("<gw>\t\t\tGateway\n"); printf ("<adist>\t\t\tAdministrative distance\n\n"); break; case 2: printf ("route_lookup <> <> \n\n"); printf ("This command indicates if the specified IPv4 address belongs to the indicated subnet\n\n"); printf ("<> \n"); printf ("<> \n\n"); break; case 3: printf ("route_print <ip_addr> <ip_mask>\n\n"); printf ("This command prints the specified route\n\n"); printf ("<ip_addr> IPv4 subnet destination address\n"); printf ("<ip_mask> Destination subnet mask\n\n"); break; case 4: printf ("route_table_remove <ip_addr> <ip_mask>\n\n"); printf ("This command removes one of the routes from the routing table\n\n"); printf ("<ip_addr> IPv4 subnet destination address\n"); printf ("<ip_mask> Destination subnet mask\n\n"); break; case 5: printf ("route_table_find <ip_addr> <ip_mask>\n\n"); printf ("This command prints the index assigned to the corresponding subnet IPv4 address\n\n"); printf ("<ip_addr> IPv4 subnet destination address\n"); printf ("<ip_mask> Destination subnet mask\n\n"); break; case 6: printf ("route_table_lookup <ip_addr>\n\n"); printf ("This command prints the best route to reach the specified destination subnet IPv4 address\n\n"); printf ("<ip_addr> IPv4 subnet destination address\n\n"); break; case 7: printf ("route_table_read <filename>\n\n"); printf ("This command reads the specified file and adds the content to the actual table\n\n"); printf ("<filename> Name of the file\n\n"); break; case 8: printf ("route_table_read <write>\n\n"); printf ("This command writes the contents of the actual table in a file\n\n"); printf ("<filename> Name of the file\n\n"); break; case 9: printf ("route_table_print\n\n"); printf ("This command prints the contents of the actual table\n\n"); break; case 10: break; case 11: break; case 12: break; default: printf ("No manual entry for %s\n\n", arg1); } break; case 11: printf ("route_create\n"); printf ("route_lookup\n"); printf ("route_print\n"); printf ("route_table_remove\n"); printf ("route_table_find\n"); printf ("route_table_lookup\n"); printf ("route_table_read\n"); printf ("route_table_write\n"); printf ("route_table_print\n"); printf ("man\n"); printf ("command_list\n"); printf ("exit\n"); printf ("clear\n"); printf ("\n"); break; case 12: exit_flag = 1; break; case 13: system ("clear"); break; } empty_buffer (arg1, sizeof (arg1)); empty_buffer (arg2, sizeof (arg2)); empty_buffer (arg3, sizeof (arg3)); empty_buffer (arg4, sizeof (arg4)); empty_buffer (arg5, sizeof (arg5)); empty_buffer (user_command, sizeof (user_command)); empty_buffer (user_input, sizeof (user_input)); empty_buffer (aux_buffer, sizeof (aux_buffer)); if (exit_flag == 1) break; } ipv4_route_table_free (ipv4_route_table_aux); return 1; }