1717#define SOCK_PATH RUNSTATEDIR "/wireguard/"
1818#define SOCK_SUFFIX ".sock"
1919
20- static FILE * userspace_interface_file (const char * iface )
20+ #ifdef __APPLE__
21+ #define NET_EXT_APP_ID "com.wireguard.macos.network-extension"
22+ #endif
23+
24+ static FILE * userspace_interface_file_at (const char * iface , const char * sock_path )
2125{
2226 struct stat sbuf ;
2327 struct sockaddr_un addr = { .sun_family = AF_UNIX };
@@ -27,7 +31,7 @@ static FILE *userspace_interface_file(const char *iface)
2731 errno = EINVAL ;
2832 if (strchr (iface , '/' ))
2933 goto out ;
30- ret = snprintf (addr .sun_path , sizeof (addr .sun_path ), SOCK_PATH "%s" SOCK_SUFFIX , iface );
34+ ret = snprintf (addr .sun_path , sizeof (addr .sun_path ), "%s%s " SOCK_SUFFIX , sock_path , iface );
3135 if (ret < 0 )
3236 goto out ;
3337 ret = stat (addr .sun_path , & sbuf );
@@ -61,15 +65,31 @@ static FILE *userspace_interface_file(const char *iface)
6165 return f ;
6266}
6367
64- static bool userspace_has_wireguard_interface (const char * iface )
68+ static FILE * userspace_interface_file (const char * iface ) {
69+ FILE * ret = userspace_interface_file_at (iface , SOCK_PATH );
70+ #ifdef __APPLE__
71+ if (ret ) {
72+ return ret ;
73+ }
74+ char sock_path [PATH_MAX ];
75+ if (snprintf (sock_path , sizeof (sock_path ), "%s/Library/Containers/" NET_EXT_APP_ID "/Data/" , getenv ("HOME" )) < 0 ) {
76+ return NULL ;
77+ }
78+
79+ ret = userspace_interface_file_at (iface , sock_path );
80+ #endif
81+ return ret ;
82+ }
83+
84+ static bool userspace_has_wireguard_interface_at (const char * iface , const char * sock_path )
6585{
6686 struct stat sbuf ;
6787 struct sockaddr_un addr = { .sun_family = AF_UNIX };
6888 int fd , ret ;
6989
7090 if (strchr (iface , '/' ))
7191 return false;
72- if (snprintf (addr .sun_path , sizeof (addr .sun_path ), SOCK_PATH "%s" SOCK_SUFFIX , iface ) < 0 )
92+ if (snprintf (addr .sun_path , sizeof (addr .sun_path ), "%s%s " SOCK_SUFFIX , sock_path , iface ) < 0 )
7393 return false;
7494 if (stat (addr .sun_path , & sbuf ) < 0 )
7595 return false;
@@ -88,15 +108,32 @@ static bool userspace_has_wireguard_interface(const char *iface)
88108 return true;
89109}
90110
91- static int userspace_get_wireguard_interfaces (struct string_list * list )
111+ static bool userspace_has_wireguard_interface (const char * iface )
112+ {
113+ bool ret = userspace_has_wireguard_interface_at (iface , SOCK_PATH );
114+ #ifdef __APPLE__
115+ if (ret ) {
116+ return true;
117+ }
118+ char sock_path [PATH_MAX ];
119+ if (snprintf (sock_path , sizeof (sock_path ), "%s/Library/Containers/" NET_EXT_APP_ID "/Data/" , getenv ("HOME" )) < 0 ) {
120+ return false;
121+ }
122+
123+ ret = userspace_has_wireguard_interface_at (iface , sock_path );
124+ #endif
125+ return ret ;
126+ }
127+
128+ static int userspace_get_wireguard_interfaces_from (const char * sock_path , struct string_list * list )
92129{
93130 DIR * dir ;
94131 struct dirent * ent ;
95132 size_t len ;
96133 char * end ;
97134 int ret = 0 ;
98135
99- dir = opendir (SOCK_PATH );
136+ dir = opendir (sock_path );
100137 if (!dir )
101138 return errno == ENOENT ? 0 : - errno ;
102139 while ((ent = readdir (dir ))) {
@@ -117,3 +154,22 @@ static int userspace_get_wireguard_interfaces(struct string_list *list)
117154 closedir (dir );
118155 return ret ;
119156}
157+
158+ static int userspace_get_wireguard_interfaces (struct string_list * list )
159+ {
160+ int ret = userspace_get_wireguard_interfaces_from (SOCK_PATH , list );
161+ #ifdef __APPLE__
162+ char sock_path [PATH_MAX ];
163+ int ret2 = snprintf (sock_path , sizeof (sock_path ), "%s/Library/Containers/" NET_EXT_APP_ID "/Data/" , getenv ("HOME" ));
164+ if (ret2 < 0 ) {
165+ goto out ;
166+ }
167+
168+ ret2 = userspace_get_wireguard_interfaces_from (sock_path , list );
169+ out :
170+ if (ret == 0 ) {
171+ ret = ret2 ;
172+ }
173+ #endif
174+ return ret ;
175+ }
0 commit comments