From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Kqafh-0001nt-0u for qemu-devel@nongnu.org; Thu, 16 Oct 2008 17:46:17 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Kqafd-0001mT-Ro for qemu-devel@nongnu.org; Thu, 16 Oct 2008 17:46:16 -0400 Received: from [199.232.76.173] (port=56113 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Kqafd-0001mP-Na for qemu-devel@nongnu.org; Thu, 16 Oct 2008 17:46:13 -0400 Received: from rv-out-0708.google.com ([209.85.198.251]:34640) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Kqafd-0001cV-7i for qemu-devel@nongnu.org; Thu, 16 Oct 2008 17:46:13 -0400 Received: by rv-out-0708.google.com with SMTP id f25so166764rvb.22 for ; Thu, 16 Oct 2008 14:46:11 -0700 (PDT) Message-ID: Date: Thu, 16 Oct 2008 15:46:11 -0600 From: "Brandon Bennett" MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Subject: [Qemu-devel] PATCH [2/2] Patches to support Juniper Olives - net udp Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This patch is to support udp -net option. This transport is compatible with dynamips udp transport. This will allow Juniper Olives (or any QEMU) to connect directly to a dynamips/dynagen/gns3 lab without the hassle of creating tun/tap interfaces and bridging. This code was taken from mmm123's version of pemu which is a modified version of QEMU for emulating Cisco Pix firewalls. The code has been updated to more fit QEMU's coding practices. Original code can be found here: http://7200emu.hacki.at/viewtopic.php?t=5383 -Brandon Bennett Index: vl.c =================================================================== --- vl.c (revision 5487) +++ vl.c (working copy) @@ -5087,6 +5087,72 @@ } +typedef struct UDPState { + VLANClientState *vc; + int fd; + struct sockaddr_in sender; +} UDPState; + +static void net_udp_send (void *opaque) +{ + UDPState *s = opaque; + uint8_t buf[4096]; + int size; + size = recvfrom(s->fd, buf, sizeof(buf), 0, NULL, NULL); + + if (size > 0) + qemu_send_packet(s->vc, buf, size); +} + +static void net_udp_receive(void *opaque, const uint8_t *buf, int size) +{ + UDPState *s = opaque; + int res; + res = sendto(s->fd, buf, size, 0, (struct sockaddr *)&s->sender, sizeof (s->sender)); +} + +static int net_udp_init(VLANState *vlan, int lport, char *rhost, int rport) +{ + UDPState *s; + struct sockaddr_in reciever; + int ret; + + s = qemu_mallocz(sizeof(DUDPState)); + if (!s) + return -1; + + s->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (s->fd < 0) { + perror("socket") + return -1; + } + + reciever.sin_family = AF_INET; + reciever.sin_addr.s_addr = INADDR_ANY; + reciever.sin_port = htons(lport); + + ret = bind(s->rfd, (struct sockaddr *)&reciever, sizeof(reciever)) + if (ret < 0) { + perror("bind"); + return -1; + } + + memset((char*)&s->sender, sizeof(s->sender), 0); + s->sender.sin_family = AF_INET; + s->sender.sin_port = htons(rport); + inet_aton(rhost, &s->sender.sin_addr); + + s->vc = qemu_new_vlan_client(vlan, net_udp_receive, NULL, s); + qemu_set_fd_handler(s->rfd, net_udp_send, NULL, s); + + snprintf(s->vc->info_str, sizeof(s->vc->info_str), + "udp: %i->%s:%i", + lport, rhost, rport); + + return 0; +} + static const char *get_opt_name(char *buf, int buf_size, const char *p) { char *q; @@ -5313,6 +5379,26 @@ ret = net_vde_init(vlan, vde_sock, vde_port, vde_group, vde_mode); } else #endif + if (!strcmp(device, "udp")) { + int sport, dport; + char buf[128]; + + if (get_param_value(buf, sizeof(buf), "dport", p) <= 0) { + fprintf(stderr, "You must specify a destination port with dport\n"); + exit(0); + } + dport = atoi(buf); + if (get_param_value(buf, sizeof(buf), "sport", p)<=0) { + fprintf(stderr, "You must specify a source port with sport\n"); + exit(0); + } + sport = atoi(buf); + if (get_param_value(buf, sizeof(buf), "daddr", p) <= 0) { + fprintf(stderr, "You must specify a destination address with daddr\n"); + exit(0); + } + ret = net_dudp_init(vlan,sport,daddr,dport); + } else { fprintf(stderr, "Unknown network device: %s\n", device); return -1; @@ -8225,6 +8311,8 @@ " Use group 'groupname' and mode 'octalmode' to change default\n" " ownership and permissions for communication port.\n" #endif + "-net udp[,vlan=n]sport=sport,dport=dport,daddr=host\n" + " connect the vlan 'n' to a udp host (for dynamips)\n" "-net none use it alone to have zero network devices; if no -net option\n" " is provided, the default is '-net nic -net user'\n" "\n"