int main(int argc, char** argv) { if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) usage(0); int32 mode = RTM_LIST; if (argc > 1) { if (!strcmp(argv[1], "delete") || !strcmp(argv[1], "del") || !strcmp(argv[1], "-d")) { // delete route if (argc < 3) usage(1); mode = RTM_DELETE; } else if (!strcmp(argv[1], "add") || !strcmp(argv[1], "-a")) { // add route if (argc < 3) usage(1); mode = RTM_ADD; } else if (!strcmp(argv[1], "get")) { // get route for destination if (argc < 3) usage(1); mode = RTM_GET; } } int32 i = 2; int32 interfaceIndex = i; bool familySpecified = false; int32 familyIndex = 0; const char *interface = NULL; sockaddr_storage destination; sockaddr_storage mask; sockaddr_storage gateway; bool hasDestination = false, hasGateway = false, hasMask = false; bool defaultRoute = false; route_entry route; memset(&route, 0, sizeof(route_entry)); while (i < argc && i < 5) { // try to parse address family if (i <= 3 && familyIndex == -1 && get_address_family(argv[i], familyIndex)) { familySpecified = true; if (i == 2) interfaceIndex = -1; } if (!strcmp(argv[i], "default")) { defaultRoute = true; route.flags = RTF_DEFAULT; i++; break; } else if (parse_address(familyIndex, argv[i], destination)) { hasDestination = true; i++; break; } i++; } if (!defaultRoute && !hasDestination && mode != RTM_LIST) usage(1); if (i == 3) interfaceIndex = -1; if (interfaceIndex != -1 && interfaceIndex < argc) interface = argv[interfaceIndex]; if (i < argc && parse_address(familyIndex, argv[i], mask)) { hasMask = true; i++; } // parse options and flags while (i < argc) { if (!strcmp(argv[i], "gw") || !strcmp(argv[i], "gateway")) { if (!parse_address(familyIndex, argv[i + 1], gateway)) { fprintf(stderr, "%s: Option 'gw' needs valid address parameter\n", kProgramName); exit(1); } hasGateway = true; i++; } else if (!strcmp(argv[i], "nm") || !strcmp(argv[i], "netmask")) { if (hasMask) { fprintf(stderr, "%s: Netmask is specified twice\n", kProgramName); exit(1); } if (!parse_address(familyIndex, argv[i + 1], mask)) { fprintf(stderr, "%s: Option 'netmask' needs valid address parameter\n", kProgramName); exit(1); } hasMask = true; i++; } else if (!strcmp(argv[i], "mtu")) { route.mtu = argv[i + 1] ? strtol(argv[i + 1], NULL, 0) : 0; if (route.mtu <= 500) { fprintf(stderr, "%s: Option 'mtu' exptected valid max transfer unit size\n", kProgramName); exit(1); } i++; } else if (!strcmp(argv[i], "host")) { route.flags |= RTF_HOST; } else if (!strcmp(argv[i], "local")) { route.flags |= RTF_LOCAL; } else if (!strcmp(argv[i], "reject")) { route.flags |= RTF_REJECT; } else usage(1); i++; } if (hasDestination) route.destination = (sockaddr *)&destination; if (hasMask) route.mask = (sockaddr *)&mask; if (hasGateway) { route.gateway = (sockaddr *)&gateway; route.flags |= RTF_GATEWAY; } // we need a socket to talk to the networking stack int socket = ::socket(kFamilies[familyIndex].family, SOCK_DGRAM, 0); if (socket < 0) { fprintf(stderr, "%s: The requested address family is not available.\n", kProgramName); return 1; } switch (mode) { case RTM_ADD: if (interface == NULL) { fprintf(stderr, "%s: You need to specify an interface when adding a route.\n", kProgramName); usage(1); } add_route(socket, interface, route); break; case RTM_DELETE: if (interface == NULL) { fprintf(stderr, "%s: You need to specify an interface when removing a route.\n", kProgramName); usage(1); } delete_route(socket, interface, route); break; case RTM_LIST: if (familySpecified) list_routes(socket, interface, route); else { for (int32 i = 0; kFamilies[i].family >= 0; i++) { int socket = ::socket(kFamilies[familyIndex].family, SOCK_DGRAM, 0); if (socket < 0) continue; list_routes(socket, interface, route); close(socket); } } break; case RTM_GET: get_route(socket, route); break; } close(socket); return 0; }
route_t *parsing_data_demo() { char buff[100]; route_t *route = NULL; SHOW_CURSE(); echo(); sleep(1); struct sigaction *pold; //io_signal_init(io_callback, pold); while(1) { RESET_STOP(); printw("[auto test] "); //clear_stdinw(); CLEAR_BUFF(buff, 100); scanw("%[^\n]\n", buff); //load route from file if (strncmp(buff, "file", 4) == 0) { char file_name[100]; sscanf(buff + 4, "%s", file_name); if (*file_name == 0) { printw("file name miss\n"); continue; } FILE *fp = fopen(file_name, "r"); if (fp == NULL) { printw("invalid file name: %s\n"); continue; } if (route != NULL) delete_route(route); route = file_create_route(fp); fclose(fp); continue; } //run with route if (strcmp(buff, "r") == 0 || strcmp(buff, "run") == 0) { if (route == NULL) { printw("no route loaded\n"); continue; } HIDE_CURSE(); noecho(); break; } //help if (strcmp(buff, "help") == 0 || strcmp(buff, "-h") == 0) { printw("use \" file [file_name] \" to load route from file\n"); printw("use \"r\" to run a test\n"); printw("use 't' or \"take off\" to take off\n"); printw("use 'y' or \"land\" to land\n"); continue; } //quit if (strcmp(buff, "q") == 0) { endwin(); BACK_TO_CLIENT(); } if (strcmp(buff, "t") == 0 || strcmp(buff, "take off") == 0) { TAKE_OFF(); continue; } if (strcmp(buff, "y") == 0 || strcmp(buff, "land") == 0) { LANDING(); continue; } printw("invalid command: %s\n", buff); } //reset_io_signal(pold); return route; }