/* Compile: gcc -o vnet -lvserver vnet.c */ #include #include #include #include #include #include #include typedef uint32_t nid_t; /* exit, silent exit, perror exit * * exit code conventions: * * 0 = OK * 1 = Wrong usage * 2 = A command failed * 3 = An opts specific function failed */ #define EXIT_USAGE 1 #define EXIT_COMMAND 2 #define EXIT_OPTS 3 #define EXIT(MSG,RC) { \ printf(MSG"; try '%s --help' for more information\n", argv[0]); \ exit(RC); \ } #define SEXIT(MSG,RC) { \ printf(MSG"\n"); \ exit(RC); \ } #define PEXIT(MSG,RC) { \ perror(MSG); \ exit(RC); \ } #define NAME "vnet" #define DESCR "Network Context Manager" #define SHORT_OPTS "hCMn:" static const struct option LONG_OPTS[] = { { "help", no_argument, 0, 'h' }, { "create", no_argument, 0, 'C' }, { "migrate", no_argument, 0, 'M' }, { "nid", required_argument, 0, 'x' }, { 0,0,0,0 } }; struct commands { bool create; bool migrate; }; struct options { nid_t nid; }; static inline void cmd_help() { printf("Usage: %s * -- *\n" "\n" "Available commands:\n" " -h,--help Show this help message\n" " -C,--create Create a new security context\n" " -M,--migrate Migrate to an existing context\n" "\n" "Available options:\n" " -n,--nid The Network Context ID\n" "\n", NAME); exit(EXIT_SUCCESS); } int main(int argc, char *argv[]) { struct commands cmds = { .create = false, .migrate = false, }; struct options opts = { .nid = -1, }; int c; while (1) { c = getopt_long(argc, argv, SHORT_OPTS, LONG_OPTS, 0); if (c == -1) break; switch (c) { case 'h': cmd_help(); break; case 'C': cmds.create = true; break; case 'M': cmds.migrate = true; break; case 'n': opts.nid = (nid_t) atoi(optarg); break; default: printf("Try '%s --help' for more information\n", argv[0]); exit(EXIT_USAGE); break; } } if (cmds.create && cmds.migrate) EXIT("Can't create and migrate at the same time", EXIT_USAGE); if (cmds.create) if (vc_net_create(opts.nid) < 0) PEXIT("Failed to create network context", EXIT_COMMAND); if (cmds.migrate) if (vc_net_migrate(opts.nid) < 0) PEXIT("Failed to migrate to network context", EXIT_COMMAND); if (argc > optind) execvp(argv[optind], argv+optind); exit(EXIT_SUCCESS); }