Skip to content

Commit 7160c75

Browse files
authored
Merge pull request #141 from pallotron/feature/no_dhcp_issue_139
feat: Allow specifying vmnet network UUID to disable DHCP (when in Host mode)
2 parents f659525 + 63acef2 commit 7160c75

File tree

4 files changed

+73
-33
lines changed

4 files changed

+73
-33
lines changed

README.md

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,28 @@ Unlike `vde_vmnet`, `socket_vmnet` does not depend on VDE.
1212
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
1313
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
1414

15-
- [Install](#install)
16-
- [From binary](#from-binary)
17-
- [From source](#from-source)
18-
- [From Homebrew](#from-homebrew)
19-
- [From MacPorts](#from-macports)
20-
- [Usage](#usage)
21-
- [QEMU](#qemu)
22-
- [Lima](#lima)
23-
- [Advanced usage](#advanced-usage)
24-
- [Multi VM](#multi-vm)
25-
- [Bridged mode](#bridged-mode)
26-
- [FAQs](#faqs)
27-
- [Why does `socket_vmnet` require root?](#why-does-socket_vmnet-require-root)
28-
- [Is it possible to run `socket_vmnet` with SETUID?](#is-it-possible-to-run-socket_vmnet-with-setuid)
15+
- [Install](#install)
16+
- [From binary](#from-binary)
17+
- [From source](#from-source)
18+
- [From Homebrew](#from-homebrew)
19+
- [From MacPorts](#from-macports)
20+
- [Usage](#usage)
21+
- [QEMU](#qemu)
22+
- [Lima](#lima)
23+
- [Advanced usage](#advanced-usage)
24+
- [Multi VM](#multi-vm)
25+
- [Bridged mode](#bridged-mode)
26+
- [FAQs](#faqs)
27+
- [Why does `socket_vmnet` require root?](#why-does-socket_vmnet-require-root)
28+
- [Is it possible to run `socket_vmnet` with SETUID?](#is-it-possible-to-run-socket_vmnet-with-setuid)
2929
- [How is socket_vmnet related to vde_vmnet?](#how-is-socket_vmnet-related-to-vde_vmnet)
30-
- [How is socket_vmnet related to QEMU-builtin vmnet support?](#how-is-socket_vmnet-related-to-qemu-builtin-vmnet-support)
31-
- [How to use static IP addresses?](#how-to-use-static-ip-addresses)
32-
- [How to reserve DHCP addresses?](#how-to-reserve-dhcp-addresses)
33-
- [IP address is not assigned](#ip-address-is-not-assigned)
34-
- [Links](#links)
35-
- [Troubleshooting](#troubleshooting)
30+
- [How is socket_vmnet related to QEMU-builtin vmnet support?](#how-is-socket_vmnet-related-to-qemu-builtin-vmnet-support)
31+
- [How to use static IP addresses?](#how-to-use-static-ip-addresses)
32+
- [How to reserve DHCP addresses?](#how-to-reserve-dhcp-addresses)
33+
- [IP address is not assigned](#ip-address-is-not-assigned)
34+
- [How to setup a vmnet host network without DHCP?](#how-to-setup-a-vmnet-host-network-without-dhcp)
35+
- [Links](#links)
36+
- [Troubleshooting](#troubleshooting)
3637

3738
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
3839

@@ -430,6 +431,20 @@ sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /usr/libexec/bootpd
430431
/usr/libexec/ApplicationFirewall/socketfilterfw --unblock /usr/libexec/bootpd
431432
```
432433

434+
### How to setup a vmnet host network without DHCP?
435+
436+
Some users may need to disable the vmnet framework's DHCP for various scenarios, such as:
437+
438+
- Create a host network where all VMs have static IPs.
439+
- Run a custom DHCP server on one VM to assign IPs to others on the same network.
440+
441+
Disabling macOS DHCP only works in `--vmnet-mode=host` if you provide a `--vmnet-network-identifier`.
442+
For example, to create a host network without DHCP on `socket_vmnet`:
443+
444+
```bash
445+
sudo /opt/socket_vmnet/bin/socket_vmnet --vmnet-mode=host --vmnet-network-identifier=$(uuidgen)
446+
```
447+
433448
## Links
434449

435450
- https://developer.apple.com/documentation/vmnet

cli.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ static void print_usage(const char *argv0) {
4848
"specified\n");
4949
printf("--vmnet-interface-id=UUID vmnet interface ID (default: "
5050
"random)\n");
51+
printf(
52+
"--vmnet-network-identifier=UUID The identifier(uuid) to uniquely identify the network. "
53+
"\n"
54+
" This property is only applicable to a vmnet_interface\n"
55+
" in VMNET_HOST_MODE.\n"
56+
" If this property is set, the vmnet_interface is added "
57+
"to \n"
58+
" an isolated network with the specified\n"
59+
" identifier. No DHCP service is provided on this "
60+
"network.\n");
5161
printf("--vmnet-nat66-prefix=PREFIX:: The IPv6 prefix to use with "
5262
"shared mode.\n");
5363
printf(" The prefix must be a ULA i.e. "
@@ -72,6 +82,7 @@ enum {
7282
CLI_OPT_VMNET_MASK,
7383
CLI_OPT_VMNET_INTERFACE_ID,
7484
CLI_OPT_VMNET_NAT66_PREFIX,
85+
CLI_OPT_VMNET_NETWORK_IDENTIFIER,
7586
};
7687

7788
struct cli_options *cli_options_parse(int argc, char *argv[]) {
@@ -82,18 +93,19 @@ struct cli_options *cli_options_parse(int argc, char *argv[]) {
8293
}
8394

8495
const struct option longopts[] = {
85-
{"socket-group", required_argument, NULL, CLI_OPT_SOCKET_GROUP },
86-
{"vmnet-mode", required_argument, NULL, CLI_OPT_VMNET_MODE },
87-
{"vmnet-interface", required_argument, NULL, CLI_OPT_VMNET_INTERFACE },
88-
{"vmnet-gateway", required_argument, NULL, CLI_OPT_VMNET_GATEWAY },
89-
{"vmnet-dhcp-end", required_argument, NULL, CLI_OPT_VMNET_DHCP_END },
90-
{"vmnet-mask", required_argument, NULL, CLI_OPT_VMNET_MASK },
91-
{"vmnet-interface-id", required_argument, NULL, CLI_OPT_VMNET_INTERFACE_ID},
92-
{"vmnet-nat66-prefix", required_argument, NULL, CLI_OPT_VMNET_NAT66_PREFIX},
93-
{"pidfile", required_argument, NULL, 'p' },
94-
{"help", no_argument, NULL, 'h' },
95-
{"version", no_argument, NULL, 'v' },
96-
{0, 0, 0, 0 },
96+
{"socket-group", required_argument, NULL, CLI_OPT_SOCKET_GROUP },
97+
{"vmnet-mode", required_argument, NULL, CLI_OPT_VMNET_MODE },
98+
{"vmnet-interface", required_argument, NULL, CLI_OPT_VMNET_INTERFACE },
99+
{"vmnet-gateway", required_argument, NULL, CLI_OPT_VMNET_GATEWAY },
100+
{"vmnet-dhcp-end", required_argument, NULL, CLI_OPT_VMNET_DHCP_END },
101+
{"vmnet-mask", required_argument, NULL, CLI_OPT_VMNET_MASK },
102+
{"vmnet-interface-id", required_argument, NULL, CLI_OPT_VMNET_INTERFACE_ID },
103+
{"vmnet-nat66-prefix", required_argument, NULL, CLI_OPT_VMNET_NAT66_PREFIX },
104+
{"vmnet-network-identifier", required_argument, NULL, CLI_OPT_VMNET_NETWORK_IDENTIFIER},
105+
{"pidfile", required_argument, NULL, 'p' },
106+
{"help", no_argument, NULL, 'h' },
107+
{"version", no_argument, NULL, 'v' },
108+
{0, 0, 0, 0 },
97109
};
98110
int opt = 0;
99111
while ((opt = getopt_long(argc, argv, "hvp:", longopts, NULL)) != -1) {
@@ -134,6 +146,12 @@ struct cli_options *cli_options_parse(int argc, char *argv[]) {
134146
case CLI_OPT_VMNET_NAT66_PREFIX:
135147
res->vmnet_nat66_prefix = strdup(optarg);
136148
break;
149+
case CLI_OPT_VMNET_NETWORK_IDENTIFIER:
150+
if (uuid_parse(optarg, res->vmnet_network_identifier) < 0) {
151+
ERRORF("Failed to parse network identifier UUID \"%s\"", optarg);
152+
goto error;
153+
}
154+
break;
137155
case 'p':
138156
res->pidfile = strdup(optarg);
139157
break;
@@ -191,7 +209,7 @@ struct cli_options *cli_options_parse(int argc, char *argv[]) {
191209
goto error;
192210
}
193211
if (res->vmnet_gateway == NULL) {
194-
if (res->vmnet_mode != VMNET_BRIDGED_MODE) {
212+
if (res->vmnet_mode != VMNET_BRIDGED_MODE && res->vmnet_mode != VMNET_HOST_MODE) {
195213
WARN("--vmnet-gateway=IP should be explicitly specified to "
196214
"avoid conflicting with other applications");
197215
}

cli.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ struct cli_options {
2020
char *vmnet_mask;
2121
// --vmnet-interface-id, corresponds to vmnet_interface_id_key
2222
uuid_t vmnet_interface_id;
23+
// --vmnet-network-identifier, corresponds to vmnet_network_identifier_key
24+
uuid_t vmnet_network_identifier;
2325
// --vmnet-nat66-prefix, corresponds to vmnet_nat66_prefix_key
2426
char *vmnet_nat66_prefix;
2527
// -p, --pidfile; writes pidfile using permissions of socket_vmnet

main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ static interface_ref start(struct state *state, struct cli_options *cliopt) {
230230
INFOF("Using network interface \"%s\"", cliopt->vmnet_interface);
231231
xpc_dictionary_set_string(dict, vmnet_shared_interface_name_key, cliopt->vmnet_interface);
232232
}
233+
234+
if (!uuid_is_null(cliopt->vmnet_network_identifier)) {
235+
xpc_dictionary_set_uuid(dict, vmnet_network_identifier_key, cliopt->vmnet_network_identifier);
236+
}
237+
233238
if (cliopt->vmnet_gateway != NULL) {
234239
xpc_dictionary_set_string(dict, vmnet_start_address_key, cliopt->vmnet_gateway);
235240
xpc_dictionary_set_string(dict, vmnet_end_address_key, cliopt->vmnet_dhcp_end);

0 commit comments

Comments
 (0)