X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=net.c;h=395ee4f5fcbf33e18be94ceedfba079e66bbf8b5;hb=2fb5a561c661f8a17a4f738a5a89addb86186e03;hp=c61f66b76c4197151988ea40acfd8cc9780b01f2;hpb=8b13c4a794e26e4fd61a71858a24d309998825e0;p=qemu diff --git a/net.c b/net.c index c61f66b..395ee4f 100644 --- a/net.c +++ b/net.c @@ -21,14 +21,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "qemu-common.h" -#include "net.h" -#include "console.h" -#include "sysemu.h" -#include "qemu-timer.h" -#include "qemu-char.h" -#include "audio/audio.h" - #include #include #include @@ -37,6 +29,9 @@ #include #include +/* Needed early for HOST_BSD etc. */ +#include "config-host.h" + #ifndef _WIN32 #include #include @@ -57,9 +52,9 @@ #include #include #include -#ifdef _BSD +#ifdef HOST_BSD #include -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__DragonFly__) #include #else #include @@ -98,12 +93,6 @@ #endif #endif -#include "qemu_socket.h" - -#if defined(CONFIG_SLIRP) -#include "libslirp.h" -#endif - #if defined(__OpenBSD__) #include #endif @@ -113,6 +102,7 @@ #endif #ifdef _WIN32 +#include #include #include #include @@ -120,6 +110,20 @@ #define memalign(align, size) malloc(size) #endif +#include "qemu-common.h" +#include "net.h" +#include "monitor.h" +#include "sysemu.h" +#include "qemu-timer.h" +#include "qemu-char.h" +#include "audio/audio.h" +#include "qemu_socket.h" + +#if defined(CONFIG_SLIRP) +#include "libslirp.h" +#endif + + static VLANState *first_vlan; /***********************************************************/ @@ -585,7 +589,7 @@ static void erase_dir(char *dir_name) char filename[1024]; /* erase all the files in the directory */ - if ((d = opendir(dir_name)) != 0) { + if ((d = opendir(dir_name)) != NULL) { for(;;) { de = readdir(d); if (!de) @@ -665,11 +669,28 @@ void net_slirp_smb(const char *exported_dir) } #endif /* !defined(_WIN32) */ -void do_info_slirp(void) +void do_info_slirp(Monitor *mon) { slirp_stats(); } +struct VMChannel { + CharDriverState *hd; + int port; +}; + +static int vmchannel_can_read(void *opaque) +{ + struct VMChannel *vmc = (struct VMChannel*)opaque; + return slirp_socket_can_recv(4, vmc->port); +} + +static void vmchannel_read(void *opaque, const uint8_t *buf, int size) +{ + struct VMChannel *vmc = (struct VMChannel*)opaque; + slirp_socket_recv(4, vmc->port, buf, size); +} + #endif /* CONFIG_SLIRP */ #if !defined(_WIN32) @@ -749,7 +770,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan, return s; } -#if defined (_BSD) || defined (__FreeBSD_kernel__) +#if defined (HOST_BSD) || defined (__FreeBSD_kernel__) static int tap_open(char *ifname, int ifname_size) { int fd; @@ -1076,8 +1097,8 @@ typedef struct NetSocketState { VLANClientState *vc; int fd; int state; /* 0 = getting length, 1 = getting data */ - int index; - int packet_len; + unsigned int index; + unsigned int packet_len; uint8_t buf[4096]; struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */ } NetSocketState; @@ -1110,7 +1131,8 @@ static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size) static void net_socket_send(void *opaque) { NetSocketState *s = opaque; - int l, size, err; + int size, err; + unsigned l; uint8_t buf1[4096]; const uint8_t *buf; @@ -1149,7 +1171,15 @@ static void net_socket_send(void *opaque) l = s->packet_len - s->index; if (l > size) l = size; - memcpy(s->buf + s->index, buf, l); + if (s->index + l <= sizeof(s->buf)) { + memcpy(s->buf + s->index, buf, l); + } else { + fprintf(stderr, "serious error: oversized packet received," + "connection terminated.\n"); + s->state = 0; + goto eoc; + } + s->index += l; buf += l; size -= l; @@ -1630,6 +1660,30 @@ int net_client_init(const char *device, const char *p) } vlan->nb_host_devs++; ret = net_slirp_init(vlan, device, name); + } else if (!strcmp(device, "channel")) { + long port; + char name[20], *devname; + struct VMChannel *vmc; + + port = strtol(p, &devname, 10); + devname++; + if (port < 1 || port > 65535) { + fprintf(stderr, "vmchannel wrong port number\n"); + return -1; + } + vmc = malloc(sizeof(struct VMChannel)); + snprintf(name, 20, "vmchannel%ld", port); + vmc->hd = qemu_chr_open(name, devname, NULL); + if (!vmc->hd) { + fprintf(stderr, "qemu: could not open vmchannel device" + "'%s'\n", devname); + return -1; + } + vmc->port = port; + slirp_add_exec(3, vmc->hd, 4, port); + qemu_chr_add_handlers(vmc->hd, vmchannel_can_read, vmchannel_read, + NULL, vmc); + ret = 0; } else #endif #ifdef _WIN32 @@ -1734,6 +1788,57 @@ void net_client_uninit(NICInfo *nd) free((void *)nd->model); } +static int net_host_check_device(const char *device) +{ + int i; + const char *valid_param_list[] = { "tap", "socket" +#ifdef CONFIG_SLIRP + ,"user" +#endif +#ifdef CONFIG_VDE + ,"vde" +#endif + }; + for (i = 0; i < sizeof(valid_param_list) / sizeof(char *); i++) { + if (!strncmp(valid_param_list[i], device, + strlen(valid_param_list[i]))) + return 1; + } + + return 0; +} + +void net_host_device_add(Monitor *mon, const char *device, const char *opts) +{ + if (!net_host_check_device(device)) { + monitor_printf(mon, "invalid host network device %s\n", device); + return; + } + net_client_init(device, opts); +} + +void net_host_device_remove(Monitor *mon, int vlan_id, const char *device) +{ + VLANState *vlan; + VLANClientState *vc; + + vlan = qemu_find_vlan(vlan_id); + if (!vlan) { + monitor_printf(mon, "can't find vlan %d\n", vlan_id); + return; + } + + for(vc = vlan->first_client; vc != NULL; vc = vc->next) + if (!strcmp(vc->name, device)) + break; + + if (!vc) { + monitor_printf(mon, "can't find device %s\n", device); + return; + } + qemu_del_vlan_client(vc); +} + int net_client_parse(const char *str) { const char *p; @@ -1754,19 +1859,19 @@ int net_client_parse(const char *str) return net_client_init(device, p); } -void do_info_network(void) +void do_info_network(Monitor *mon) { VLANState *vlan; VLANClientState *vc; for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) { - term_printf("VLAN %d devices:\n", vlan->id); + monitor_printf(mon, "VLAN %d devices:\n", vlan->id); for(vc = vlan->first_client; vc != NULL; vc = vc->next) - term_printf(" %s: %s\n", vc->name, vc->info_str); + monitor_printf(mon, " %s: %s\n", vc->name, vc->info_str); } } -int do_set_link(const char *name, const char *up_or_down) +int do_set_link(Monitor *mon, const char *name, const char *up_or_down) { VLANState *vlan; VLANClientState *vc = NULL; @@ -1778,7 +1883,7 @@ int do_set_link(const char *name, const char *up_or_down) done: if (!vc) { - term_printf("could not find network device '%s'", name); + monitor_printf(mon, "could not find network device '%s'", name); return 0; } @@ -1787,8 +1892,8 @@ done: else if (strcmp(up_or_down, "down") == 0) vc->link_down = 1; else - term_printf("invalid link status '%s'; only 'up' or 'down' valid\n", - up_or_down); + monitor_printf(mon, "invalid link status '%s'; only 'up' or 'down' " + "valid\n", up_or_down); if (vc->link_status_changed) vc->link_status_changed(vc);