Esempio n. 1
0
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;
}