R&D/VRouter KVM UDP 패치 sunshout1 2009. 4. 9. 14:48 qemu에서 수정코드 (Language : c)+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" qemu의 수정코드인데 -net udp를 하게 만들었다. 이렇게 만들어도 되고 지금 KVM에 존재하는 socket 코드안에 수정하는 방법도 있을거 같다. 728x90