aboutsummaryrefslogtreecommitdiffstats
path: root/src/dumm/main.c
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2007-07-25 13:23:45 +0000
committerMartin Willi <martin@strongswan.org>2007-07-25 13:23:45 +0000
commitf85fdda83598cdfde287ee0acb5581d9cb2f261b (patch)
treeb83ef7735a7eb81b9ae447b8045b0e011eb92bba /src/dumm/main.c
parent5c7da9d402a71992a5dc47c5ab25fd6f1479f5a7 (diff)
downloadstrongswan-f85fdda83598cdfde287ee0acb5581d9cb2f261b.tar.bz2
strongswan-f85fdda83598cdfde287ee0acb5581d9cb2f261b.tar.xz
added dynamic interface manipulation for guests
management of tap devices on the host
Diffstat (limited to 'src/dumm/main.c')
-rw-r--r--src/dumm/main.c234
1 files changed, 218 insertions, 16 deletions
diff --git a/src/dumm/main.c b/src/dumm/main.c
index 26896c2df..7e22ddfd6 100644
--- a/src/dumm/main.c
+++ b/src/dumm/main.c
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
#define _GNU_SOURCE
#include <stdio.h>
@@ -20,7 +35,7 @@ static void usage()
}
/**
- * show usage information (commandline arguments)
+ * help for dumm root shell
*/
static void help()
{
@@ -29,15 +44,29 @@ static void help()
printf(" kernel=<uml-kernel>\n");
printf(" master=<read-only root files>\n");
printf(" memory=<guest memory in MB>\n");
- printf("guests list running guests\n");
+ printf("list list running guests\n");
+ printf("guest <name> open guest menu for <name>\n");
printf("help show this help\n");
printf("quit kill quests and exit\n");
}
+
+/**
+ * help for guest shell
+ */
+static void help_guest()
+{
+ printf("addif <name> add an interface to the guest\n");
+ printf("delif <name> remove the interface\n");
+ printf("listif list guests interfaces\n");
+ printf("help show this help\n");
+ printf("quit quit the guest menu\n");
+}
+
/**
* start an UML guest
*/
-static void start(umli_t *umli, char *line)
+static void start(dumm_t *dumm, char *line)
{
enum {
NAME = 0,
@@ -101,7 +130,7 @@ static void start(umli_t *umli, char *line)
mem = 128;
}
- if (umli->start_guest(umli, name, kernel, master, mem))
+ if (dumm->start_guest(dumm, name, kernel, master, mem))
{
printf("starting guest '%s'\n", name);
}
@@ -112,19 +141,187 @@ static void start(umli_t *umli, char *line)
}
/**
- * list running UML guests
+ * add an iface to a guest
+ */
+static void add_if(guest_t *guest, char *name)
+{
+ iface_t *iface;
+
+ iface = guest->create_iface(guest, name);
+ if (iface)
+ {
+ printf("created guest interface '%s' connected to '%s'\n",
+ iface->get_guest(iface), iface->get_host(iface));
+ }
+ else
+ {
+ printf("failed to create guest interface\n");
+ }
+}
+
+/**
+ * delete an iface from a guest
*/
-static void guests(umli_t *umli)
+static void del_if(guest_t *guest, char *name)
{
+ iface_t *iface;
+ iterator_t *iterator;
+ bool found = FALSE;
+
+ iterator = guest->create_iface_iterator(guest);
+ while (iterator->iterate(iterator, (void**)&iface))
+ {
+ if (streq(name, iface->get_guest(iface)))
+ {
+ iterator->remove(iterator);
+ printf("removing interface '%s' ('%s') from %s\n",
+ iface->get_guest(iface), iface->get_host(iface),
+ guest->get_name(guest));
+ iface->destroy(iface);
+ found = TRUE;
+ break;
+ }
+ }
+ iterator->destroy(iterator);
+ if (!found)
+ {
+ printf("guest '%s' has no interface named '%s'\n",
+ guest->get_name(guest), name);
+ }
+}
+
+/**
+ * list interfaces on a guest
+ */
+static void list_if(guest_t *guest)
+{
+ iface_t *iface;
+ iterator_t *iterator;
+
+ iterator = guest->create_iface_iterator(guest);
+ while (iterator->iterate(iterator, (void**)&iface))
+ {
+ printf("'%s' => '%s'\n", iface->get_guest(iface), iface->get_host(iface));
+
+ }
+ iterator->destroy(iterator);
+}
+
+/**
+ * subshell for guests
+ */
+static void guest(dumm_t *dumm, char *name)
+{
+ char *line = NULL;
+ char prompt[32];
+ int len;
iterator_t *iterator;
guest_t *guest;
+ bool found = FALSE;
- iterator = umli->create_guest_iterator(umli);
+ iterator = dumm->create_guest_iterator(dumm);
while (iterator->iterate(iterator, (void**)&guest))
{
- printf("%s\n", guest->get_name(guest));
+ if (streq(name, guest->get_name(guest)))
+ {
+ found = TRUE;
+ }
}
iterator->destroy(iterator);
+ if (!found)
+ {
+ printf("guest '%s' not found\n", name);
+ return;
+ }
+
+ len = snprintf(prompt, sizeof(prompt), "dumm@%s# ", name);
+ if (len < 0 || len >= sizeof(prompt))
+ {
+ return;
+ }
+
+ while (TRUE)
+ {
+ enum {
+ QUIT = 0,
+ HELP,
+ ADDIF,
+ DELIF,
+ LISTIF,
+ };
+ char *const opts[] = {
+ [QUIT] = "quit",
+ [HELP] = "help",
+ [ADDIF] = "addif",
+ [DELIF] = "delif",
+ [LISTIF] = "listif",
+ NULL
+ };
+ char *pos, *value;
+
+ free(line);
+ line = readline(prompt);
+ if (line == NULL || *line == '\0')
+ {
+ continue;
+ }
+ add_history(line);
+ pos = line;
+ while (*pos != '\0')
+ {
+ if (*pos == ' ')
+ {
+ *pos = ',';
+ }
+ pos++;
+ }
+ pos = line;
+ switch (getsubopt(&pos, opts, &value))
+ {
+ case QUIT:
+ free(line);
+ break;
+ case HELP:
+ help_guest();
+ continue;
+ case ADDIF:
+ add_if(guest, pos);
+ continue;
+ case DELIF:
+ del_if(guest, pos);
+ continue;
+ case LISTIF:
+ list_if(guest);
+ continue;
+ default:
+ printf("command unknown: '%s'\n", line);
+ continue;
+ }
+ break;
+ }
+}
+
+/**
+ * list running UML guests
+ */
+static void list(dumm_t *dumm)
+{
+ iterator_t *guests, *ifaces;
+ guest_t *guest;
+ iface_t *iface;
+
+ guests = dumm->create_guest_iterator(dumm);
+ while (guests->iterate(guests, (void**)&guest))
+ {
+ printf("%s\n", guest->get_name(guest));
+ ifaces = guest->create_iface_iterator(guest);
+ while (ifaces->iterate(ifaces, (void**)&iface))
+ {
+ printf(" '%s' => '%s'\n", iface->get_guest(iface), iface->get_host(iface));
+ }
+ ifaces->destroy(ifaces);
+ }
+ guests->destroy(guests);
}
/**
@@ -132,7 +329,7 @@ static void guests(umli_t *umli)
*/
int main(int argc, char *argv[])
{
- umli_t *umli;
+ dumm_t *dumm;
char *line = NULL;
while (TRUE)
@@ -164,7 +361,7 @@ int main(int argc, char *argv[])
break;
}
- umli = umli_create();
+ dumm = dumm_create();
while (TRUE)
{
@@ -172,13 +369,15 @@ int main(int argc, char *argv[])
QUIT = 0,
HELP,
START,
- GUESTS,
+ LIST,
+ GUEST,
};
char *const opts[] = {
[QUIT] = "quit",
[HELP] = "help",
[START] = "start",
- [GUESTS] = "guests",
+ [LIST] = "list",
+ [GUEST] = "guest",
NULL
};
char *pos, *value;
@@ -210,10 +409,13 @@ int main(int argc, char *argv[])
help();
continue;
case START:
- start(umli, pos);
+ start(dumm, pos);
+ continue;
+ case LIST:
+ list(dumm);
continue;
- case GUESTS:
- guests(umli);
+ case GUEST:
+ guest(dumm, pos);
continue;
default:
printf("command unknown: '%s'\n", line);
@@ -221,7 +423,7 @@ int main(int argc, char *argv[])
}
break;
}
- umli->destroy(umli);
+ dumm->destroy(dumm);
clear_history();
return 0;
}