qemu_send_packet(&s->nc, s->buf, size);
}
-static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
+static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr *localaddr)
{
struct ip_mreq imr;
int fd;
/* Add host to multicast group */
imr.imr_multiaddr = mcastaddr->sin_addr;
- imr.imr_interface.s_addr = htonl(INADDR_ANY);
+ if (localaddr) {
+ imr.imr_interface = *localaddr;
+ } else {
+ imr.imr_interface.s_addr = htonl(INADDR_ANY);
+ }
ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(const char *)&imr, sizeof(struct ip_mreq));
goto fail;
}
+ /* If a bind address is given, only send packets from that address */
+ if (localaddr != NULL) {
+ ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, localaddr, sizeof(*localaddr));
+ if (ret < 0) {
+ perror("setsockopt(IP_MULTICAST_IF)");
+ goto fail;
+ }
+ }
+
socket_set_nonblock(fd);
return fd;
fail:
return NULL;
}
/* clone dgram socket */
- newfd = net_socket_mcast_create(&saddr);
+ newfd = net_socket_mcast_create(&saddr, NULL);
if (newfd < 0) {
/* error already reported by net_socket_mcast_create() */
close(fd);
static int net_socket_mcast_init(VLANState *vlan,
const char *model,
const char *name,
- const char *host_str)
+ const char *host_str,
+ const char *localaddr_str)
{
NetSocketState *s;
int fd;
struct sockaddr_in saddr;
+ struct in_addr localaddr, *param_localaddr;
if (parse_host_port(&saddr, host_str) < 0)
return -1;
+ if (localaddr_str != NULL) {
+ if (inet_aton(localaddr_str, &localaddr) == 0)
+ return -1;
+ param_localaddr = &localaddr;
+ } else {
+ param_localaddr = NULL;
+ }
- fd = net_socket_mcast_create(&saddr);
+ fd = net_socket_mcast_create(&saddr, param_localaddr);
if (fd < 0)
return -1;
if (qemu_opt_get(opts, "listen") ||
qemu_opt_get(opts, "connect") ||
- qemu_opt_get(opts, "mcast")) {
- error_report("listen=, connect= and mcast= is invalid with fd=");
+ qemu_opt_get(opts, "mcast") ||
+ qemu_opt_get(opts, "localaddr")) {
+ error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=\n");
return -1;
}
if (qemu_opt_get(opts, "fd") ||
qemu_opt_get(opts, "connect") ||
- qemu_opt_get(opts, "mcast")) {
- error_report("fd=, connect= and mcast= is invalid with listen=");
+ qemu_opt_get(opts, "mcast") ||
+ qemu_opt_get(opts, "localaddr")) {
+ error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=\n");
return -1;
}
if (qemu_opt_get(opts, "fd") ||
qemu_opt_get(opts, "listen") ||
- qemu_opt_get(opts, "mcast")) {
- error_report("fd=, listen= and mcast= is invalid with connect=");
+ qemu_opt_get(opts, "mcast") ||
+ qemu_opt_get(opts, "localaddr")) {
+ error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=\n");
return -1;
}
return -1;
}
} else if (qemu_opt_get(opts, "mcast")) {
- const char *mcast;
+ const char *mcast, *localaddr;
if (qemu_opt_get(opts, "fd") ||
qemu_opt_get(opts, "connect") ||
}
mcast = qemu_opt_get(opts, "mcast");
+ localaddr = qemu_opt_get(opts, "localaddr");
- if (net_socket_mcast_init(vlan, "socket", name, mcast) == -1) {
+ if (net_socket_mcast_init(vlan, "socket", name, mcast, localaddr) == -1) {
return -1;
}
} else {
#endif
"-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
" connect the vlan 'n' to another VLAN using a socket connection\n"
- "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n"
+ "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port[,localaddr=addr]]\n"
" connect the vlan 'n' to multicast maddr and port\n"
+ " use 'localaddr=addr' to specify the host address to send packets from\n"
#ifdef CONFIG_VDE
"-net vde[,vlan=n][,name=str][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
" connect the vlan 'n' to port 'n' of a vde switch running\n"
-net socket,connect=127.0.0.1:1234
@end example
-@item -net socket[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}] [,mcast=@var{maddr}:@var{port}]
+@item -net socket[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}][,mcast=@var{maddr}:@var{port}[,localaddr=@var{addr}]]
Create a VLAN @var{n} shared with another QEMU virtual
machines using a UDP multicast socket, effectively making a bus for
/path/to/linux ubd0=/path/to/root_fs eth0=mcast
@end example
+Example (send packets from host's 1.2.3.4):
+@example
+qemu linux.img -net nic,macaddr=52:54:00:12:34:56 \
+ -net socket,mcast=239.192.168.1:1102,localaddr=1.2.3.4
+@end example
+
@item -net vde[,vlan=@var{n}][,name=@var{name}][,sock=@var{socketpath}] [,port=@var{n}][,group=@var{groupname}][,mode=@var{octalmode}]
Connect VLAN @var{n} to PORT @var{n} of a vde switch running on host and
listening for incoming connections on @var{socketpath}. Use GROUP @var{groupname}