void run_menu() { int rv, i; struct timeval tv; // Start timeout right away so updates will be sent tv.tv_sec = 0; tv.tv_usec = 10; while (1) { // Check for dropped connections for (i = 0; i < MAX_SERVERS; ++i) { if (connect_out[i].in_use == 0) continue; if (difftime(time(NULL), connect_out[i].last_time) > (update_int * 3)) if (connect_out[i].time_out == 0) timeout_connect(i); } // Reset the file descriptor set fds_reset(); rv = select(highsock, &fdread, NULL, NULL, &tv); if (rv < 0) die ("select failed"); // Timeout occured, send updates and reset else if (rv == 0) { send_packet_to_neighbors(); // Reset timer (centiseconds) tv.tv_sec = update_int; tv.tv_usec = 0; continue; } // Input detected from stdin, run the menu if (FD_ISSET(fileno(stdin), &fdread)) { process_menu_input(); continue; } // Input detected on socket if (FD_ISSET(connect_in.fd, &fdread)) { // Read packet, update routing table, and display read_packet(); update_route(); } } }
int get_route_table_by_snmp(struct route_table *rt) { ipRouteTable *rtable = NULL ; // getIpRouteTable(rt->routerip, &rtable); getIpForwardTable(rt->routerip, &rtable); if(rtable == NULL) { printf("Get routing table failed\n"); return NULL; } ipRouteTable* r = rtable->next; int total = 0; while(r!=NULL){ struct route* newroute = malloc_z(struct route); inet_pton(AF_INET, r->ipRouteDest ,&newroute->prefix.prefix); newroute->prefix.family = AF_INET; newroute->prefix.prefixlen = get_prefix_length(r->ipRouteMask); inet_pton(AF_INET, r->ipRouteNextHop, &newroute->gateway); newroute->interface_id = atoi(r->ipRouteIfIndex); newroute->metric = atoi(r->ipRouteMetric); if ( strcmp(r->ipRouteType,"local") == 0 ) newroute->type = ROUTE_TYPE_LOCAL; else newroute->type = ROUTE_TYPE_REMOTE; newroute->dirty = FRESH_STATUS; struct route** rr = find_before_route(rt->routes, *newroute); if( rr== NULL) add_route(rt->routes, newroute); else update_route(rr, newroute); total++; r = r->next; } freeIpRouteTable(rtable); rt->route_table_len = total; }
/* * Process an incoming route report message. */ void accept_report(u_int32_t src, u_int32_t dst, char *p, int datalen, u_int32_t level) { vifi_t vifi; register int width, i, nrt = 0; int metric; u_int32_t mask; u_int32_t origin; struct newrt rt[4096]; if ((vifi = find_vif(src, dst)) == NO_VIF) { logit(LOG_INFO, 0, "ignoring route report from non-neighbor %s", inet_fmt(src, s1)); return; } if (!update_neighbor(vifi, src, DVMRP_REPORT, NULL, 0, level)) return; if (datalen > 2*4096) { logit(LOG_INFO, 0, "ignoring oversize (%d bytes) route report from %s", datalen, inet_fmt(src, s1)); return; } while (datalen > 0) { /* Loop through per-mask lists. */ if (datalen < 3) { logit(LOG_WARNING, 0, "received truncated route report from %s", inet_fmt(src, s1)); return; } ((u_char *)&mask)[0] = 0xff; width = 1; if ((((u_char *)&mask)[1] = *p++) != 0) width = 2; if ((((u_char *)&mask)[2] = *p++) != 0) width = 3; if ((((u_char *)&mask)[3] = *p++) != 0) width = 4; if (!inet_valid_mask(ntohl(mask))) { logit(LOG_WARNING, 0, "%s reports bogus netmask 0x%08x (%s)", inet_fmt(src, s1), ntohl(mask), inet_fmt(mask, s2)); return; } datalen -= 3; do { /* Loop through (origin, metric) pairs */ if (datalen < width + 1) { logit(LOG_WARNING, 0, "received truncated route report from %s", inet_fmt(src, s1)); return; } origin = 0; for (i = 0; i < width; ++i) ((char *)&origin)[i] = *p++; metric = *p++; datalen -= width + 1; rt[nrt].mask = mask; rt[nrt].origin = origin; rt[nrt].metric = (metric & 0x7f); ++nrt; } while (!(metric & 0x80)); } qsort((char*)rt, nrt, sizeof(rt[0]), compare_rts); start_route_updates(); /* * If the last entry is default, change mask from 0xff000000 to 0 */ if (rt[nrt-1].origin == 0) rt[nrt-1].mask = 0; logit(LOG_DEBUG, 0, "Updating %d routes from %s to %s", nrt, inet_fmt(src, s1), inet_fmt(dst, s2)); for (i = 0; i < nrt; ++i) { if (i != 0 && rt[i].origin == rt[i-1].origin && rt[i].mask == rt[i-1].mask) { logit(LOG_WARNING, 0, "%s reports duplicate route for %s", inet_fmt(src, s1), inet_fmts(rt[i].origin, rt[i].mask, s2)); continue; } update_route(rt[i].origin, rt[i].mask, rt[i].metric, src, vifi); } if (routes_changed && !delay_change_reports) report_to_all_neighbors(CHANGED_ROUTES); }
// Process menu input and call functions based on input void process_menu_input() { char command[BUFF_SIZE]; char *buffer; int index1, index2; uint32_t cost; // Get the command... if (fgets(command, BUFF_SIZE, stdin) == NULL) die ("Input Error"); buffer = strtok(command, " \n\r\0"); if (strcmp(command, "help") == 0) { display_menu_help(); } else if (strcmp(command, "update") == 0) { buffer = strtok(NULL, " \n"); if (buffer == NULL) die("update ERROR invalid input"); index1 = get_index_from_id(atoi(buffer)); buffer = strtok(NULL, " \n"); if (buffer == NULL) die("update ERROR invalid input\n"); index2 = get_index_from_id(atoi(buffer)); if (index1 < 0 || index2 < 0) printf("update ERROR invalid id\n"); else if ((my_server->index != index1 && connect_out[index1].in_use == 0) || connect_out[index2].in_use == 0) printf("update ERROR ids must be active\n"); else { buffer = strtok(NULL, "\n"); if (strcmp(buffer, "inf") == 0) cost = INFINITY; else cost = atoi(buffer); if (cost < 0) printf("update ERROR invalid cost\n"); else { // Be sure to update the actual cost if it involves ourselves if (index1 == my_server->index) route[index2].cost = cost; else if (index2 == my_server->index) route[index1].cost = cost; // Otherwise just update the "cost" distance in our topology topology.server[index1].cost[index2] = cost; printf("update SUCCESS\n"); update_route(); } } } else if (strcmp(command, "disable") == 0) { buffer = strtok(NULL, "\n"); index1 = get_index_from_id(atoi(buffer)); if (index1 < 0) printf("disable ERROR invalid id\n"); else if (connect_out[index1].in_use == 0) printf("disable ERROR id not in use\n"); else { disable_connect(index1); printf("disable SUCCESS\n"); } } else if (strcmp(command, "crash") == 0) { for (index1 = 0; index1 < MAX_SERVERS; ++index1) disable_connect(index1); connect_in.in_use = 0; printf("crash SUCCESS\n"); } else if (strcmp(command, "step") == 0) { if (connect_in.in_use == 0) printf("step ERROR server is crashed\n"); else { send_packet_to_neighbors(); printf("step SUCCESS\n"); } } else if (strcmp(command, "display") == 0) { display_route(); printf("display SUCCESS\n"); } else if (strcmp(command, "packets") == 0) { printf("Packets received since last update: %d\npackets SUCCESS\n", packets_rcvd); packets_rcvd = 0; } else if (strcmp(command, "myip") == 0) { printf("My IP: %s (real: %s)\nmyip SUCCESS\n", char4_to_str(my_server->ip), getmyip()); } else if (strcmp(command, "myport") == 0) { printf("My Port #: %i\nmyport SUCCESS\n", my_server->port); } else if (strcmp(command, "cls") == 0) { clear_screen(); } else if (strcmp(command, "exit") == 0) die ("\t\tGOODBYE :)"); else printf("Unrecognized command: type help for help\n"); fflush(NULL); }