diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2012-12-03 22:58:19 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2012-12-03 22:58:19 +0000 |
commit | 392560f8c6a71484973ecc0947d4df5634af279b (patch) | |
tree | b0d04d0ba25ccae1fb340312ede983898692a640 /src/vpn | |
parent | c09c2682f8853a3775eed00265f4ba00f9f224ac (diff) | |
download | gnunet-392560f8c6a71484973ecc0947d4df5634af279b.tar.gz gnunet-392560f8c6a71484973ecc0947d4df5634af279b.zip |
Added logics to install virtual networks interfaces for gnunet-vpn in
win32 based on the info that can be found in the MSDN.
Current revision: http://msdn.microsoft.com/en-us/library/windows/hardware/ff549791%28v=vs.85%29.aspx
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/gnunet-helper-vpn-windows.c | 241 |
1 files changed, 187 insertions, 54 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c index 8ac68132e..b805811f6 100644 --- a/src/vpn/gnunet-helper-vpn-windows.c +++ b/src/vpn/gnunet-helper-vpn-windows.c | |||
@@ -16,7 +16,7 @@ | |||
16 | along with GNUnet; see the file COPYING. If not, write to the | 16 | along with GNUnet; see the file COPYING. If not, write to the |
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file vpn/gnunet-helper-vpn-windows.c | 22 | * @file vpn/gnunet-helper-vpn-windows.c |
@@ -31,8 +31,18 @@ | |||
31 | * | 31 | * |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <stdio.h> | ||
35 | #include <windows.h> | ||
36 | #include <setupapi.h> | ||
34 | #include "platform.h" | 37 | #include "platform.h" |
35 | 38 | ||
39 | //#include <tchar.h> | ||
40 | //#include <stdlib.h> | ||
41 | //#include <regstr.h> | ||
42 | //#include <string.h> | ||
43 | //#include <malloc.h> | ||
44 | //#include <objbase.h> | ||
45 | |||
36 | /** | 46 | /** |
37 | * Need 'struct GNUNET_MessageHeader'. | 47 | * Need 'struct GNUNET_MessageHeader'. |
38 | */ | 48 | */ |
@@ -54,6 +64,20 @@ | |||
54 | */ | 64 | */ |
55 | #define MAX_SIZE 65536 | 65 | #define MAX_SIZE 65536 |
56 | 66 | ||
67 | /** | ||
68 | * This is our own local instance of a virtual network interface | ||
69 | * It is (somewhat) equivalent to using tun/tap in unixoid systems | ||
70 | * | ||
71 | * Upon initialization, we create such an device node. | ||
72 | * Upon termination, we remove it again. | ||
73 | * | ||
74 | * If we crash this device might stay around. | ||
75 | */ | ||
76 | HDEVINFO DeviceInfo = INVALID_HANDLE_VALUE; | ||
77 | SP_DEVINFO_DATA DeviceNode; | ||
78 | TCHAR class[128]; | ||
79 | GUID guid; | ||
80 | |||
57 | /** | 81 | /** |
58 | * Creates a tun-interface called dev; | 82 | * Creates a tun-interface called dev; |
59 | * | 83 | * |
@@ -67,17 +91,16 @@ init_tun (char *dev) | |||
67 | int fd; | 91 | int fd; |
68 | 92 | ||
69 | if (NULL == dev) | 93 | if (NULL == dev) |
70 | { | 94 | { |
71 | errno = EINVAL; | 95 | errno = EINVAL; |
72 | return -1; | 96 | return -1; |
73 | } | 97 | } |
74 | 98 | ||
75 | /* Hello, I am a stub function! I did my job, yay me! */ | 99 | /* Hello, I am a stub function! I did my job, yay me! */ |
76 | 100 | ||
77 | return fd; | 101 | return fd; |
78 | } | 102 | } |
79 | 103 | ||
80 | |||
81 | /** | 104 | /** |
82 | * @brief Sets the IPv6-Address given in address on the interface dev | 105 | * @brief Sets the IPv6-Address given in address on the interface dev |
83 | * | 106 | * |
@@ -88,7 +111,7 @@ init_tun (char *dev) | |||
88 | static void | 111 | static void |
89 | set_address6 (const char *dev, const char *address, unsigned long prefix_len) | 112 | set_address6 (const char *dev, const char *address, unsigned long prefix_len) |
90 | { | 113 | { |
91 | int fd=0; | 114 | int fd = 0; |
92 | 115 | ||
93 | /* | 116 | /* |
94 | * parse the new address | 117 | * parse the new address |
@@ -113,13 +136,12 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len) | |||
113 | 136 | ||
114 | 137 | ||
115 | if (0 != close (fd)) | 138 | if (0 != close (fd)) |
116 | { | 139 | { |
117 | fprintf (stderr, "close failed: %s\n", strerror (errno)); | 140 | fprintf (stderr, "close failed: %s\n", strerror (errno)); |
118 | exit (1); | 141 | exit (1); |
119 | } | 142 | } |
120 | } | 143 | } |
121 | 144 | ||
122 | |||
123 | /** | 145 | /** |
124 | * @brief Sets the IPv4-Address given in address on the interface dev | 146 | * @brief Sets the IPv4-Address given in address on the interface dev |
125 | * | 147 | * |
@@ -130,7 +152,7 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len) | |||
130 | static void | 152 | static void |
131 | set_address4 (const char *dev, const char *address, const char *mask) | 153 | set_address4 (const char *dev, const char *address, const char *mask) |
132 | { | 154 | { |
133 | int fd=0; | 155 | int fd = 0; |
134 | 156 | ||
135 | /* | 157 | /* |
136 | * Parse the address | 158 | * Parse the address |
@@ -161,13 +183,119 @@ set_address4 (const char *dev, const char *address, const char *mask) | |||
161 | 183 | ||
162 | 184 | ||
163 | if (0 != close (fd)) | 185 | if (0 != close (fd)) |
164 | { | 186 | { |
165 | fprintf (stderr, "close failed: %s\n", strerror (errno)); | 187 | fprintf (stderr, "close failed: %s\n", strerror (errno)); |
166 | (void) close (fd); | 188 | (void) close (fd); |
167 | exit (1); | 189 | exit (1); |
168 | } | 190 | } |
169 | } | 191 | } |
170 | 192 | ||
193 | static boolean | ||
194 | setup_interface () | ||
195 | { | ||
196 | /* | ||
197 | * where to find our inf-file. (+ the "full" path, after windows found") | ||
198 | * | ||
199 | * We do not directly input all the props here, because openvpn will update | ||
200 | * these details over time. | ||
201 | */ | ||
202 | TCHAR InfFile[] = "tapw32.inf"; | ||
203 | TCHAR hwid[] = "TAP0901"; | ||
204 | TCHAR * InfFilePath; | ||
205 | TCHAR * hwIdList; | ||
206 | |||
207 | /** | ||
208 | * Locate the inf-file, we need to store it somewhere where the system can | ||
209 | * find it. A good choice would be CWD/PDW or %WINDIR$\system32\ | ||
210 | * | ||
211 | * TODO: Finde a more sane way to do this! | ||
212 | */ | ||
213 | |||
214 | InfFilePath = calloc (MAX_PATH, sizeof (TCHAR)); | ||
215 | if (InfFilePath == NULL) | ||
216 | { | ||
217 | return FALSE; | ||
218 | } | ||
219 | GetFullPathName (InfFile, MAX_PATH, InfFilePath, NULL); | ||
220 | |||
221 | /** | ||
222 | * Set the device's hardware ID and add it to a list. | ||
223 | * This information will later on identify this device in registry. | ||
224 | * | ||
225 | * TODO: Currently we just use TAP0901 as HWID, | ||
226 | * but we might want to add additional information | ||
227 | */ | ||
228 | hwIdList = calloc (LINE_LEN + 4, sizeof (TCHAR)); | ||
229 | if (hwIdList == NULL) | ||
230 | { | ||
231 | goto cleanup1; | ||
232 | } | ||
233 | strncpy (hwIdList, hwid, LINE_LEN); | ||
234 | |||
235 | /** | ||
236 | * Bootstrap our device info using the drivers inf-file | ||
237 | */ | ||
238 | if (!SetupDiGetINFClass (InfFilePath, | ||
239 | &guid, | ||
240 | class, sizeof (class) / sizeof (TCHAR), | ||
241 | NULL)) | ||
242 | { | ||
243 | goto cleanup2; | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * Collect all the other needed information... | ||
248 | * let the system fill our this form | ||
249 | */ | ||
250 | DeviceInfo = SetupDiCreateDeviceInfoList (&guid, NULL); | ||
251 | if (DeviceInfo == INVALID_HANDLE_VALUE) | ||
252 | { | ||
253 | goto cleanup3; | ||
254 | } | ||
255 | DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); | ||
256 | if (!SetupDiCreateDeviceInfo (DeviceInfo, | ||
257 | class, | ||
258 | &guid, | ||
259 | NULL, | ||
260 | NULL, | ||
261 | DICD_GENERATE_ID, | ||
262 | &DeviceNode)) | ||
263 | { | ||
264 | goto cleanup3; | ||
265 | } | ||
266 | |||
267 | /* Deploy all the information collected into the registry */ | ||
268 | if (!SetupDiSetDeviceRegistryProperty (DeviceInfo, | ||
269 | &DeviceNode, | ||
270 | SPDRP_HARDWAREID, | ||
271 | (LPBYTE) hwIdList, | ||
272 | (lstrlen (hwIdList) + 2) * sizeof (TCHAR))) | ||
273 | { | ||
274 | goto cleanup3; | ||
275 | } | ||
276 | /* Install our new class(=device) into the system */ | ||
277 | if (!SetupDiCallClassInstaller (DIF_REGISTERDEVICE, | ||
278 | DeviceInfo, | ||
279 | &DeviceNode)) | ||
280 | { | ||
281 | goto cleanup3; | ||
282 | } | ||
283 | |||
284 | return TRUE; | ||
285 | |||
286 | //disabled for debug-reasons... | ||
287 | cleanup3: | ||
288 | //GNUNET_free(DeviceInfo); | ||
289 | ; | ||
290 | cleanup2: | ||
291 | //GNUNET_free(hwIdList); | ||
292 | ; | ||
293 | cleanup1: | ||
294 | //GNUNET_free(InfFilePath); | ||
295 | ; | ||
296 | return FALSE; | ||
297 | |||
298 | } | ||
171 | 299 | ||
172 | /** | 300 | /** |
173 | * Start forwarding to and from the tunnel. | 301 | * Start forwarding to and from the tunnel. |
@@ -194,7 +322,6 @@ run (int fd_tun) | |||
194 | /* Hello, I am a stub function! I did my job, yay me! */ | 322 | /* Hello, I am a stub function! I did my job, yay me! */ |
195 | } | 323 | } |
196 | 324 | ||
197 | |||
198 | /** | 325 | /** |
199 | * Open VPN tunnel interface. | 326 | * Open VPN tunnel interface. |
200 | * | 327 | * |
@@ -206,6 +333,7 @@ run (int fd_tun) | |||
206 | * 4: IPv4 address (1.2.3.4), "-" to disable | 333 | * 4: IPv4 address (1.2.3.4), "-" to disable |
207 | * 5: IPv4 netmask (255.255.0.0), ignored if #4 is "-" | 334 | * 5: IPv4 netmask (255.255.0.0), ignored if #4 is "-" |
208 | */ | 335 | */ |
336 | |||
209 | int | 337 | int |
210 | main (int argc, char **argv) | 338 | main (int argc, char **argv) |
211 | { | 339 | { |
@@ -214,49 +342,54 @@ main (int argc, char **argv) | |||
214 | int global_ret; | 342 | int global_ret; |
215 | 343 | ||
216 | if (6 != argc) | 344 | if (6 != argc) |
217 | { | 345 | { |
218 | fprintf (stderr, "Fatal: must supply 5 arguments!\n"); | 346 | fprintf (stderr, "Fatal: must supply 5 arguments!\n"); |
219 | return 1; | 347 | return 1; |
220 | } | 348 | } |
221 | 349 | ||
222 | /* | 350 | /* |
223 | * strncpy (dev, argv[1], IFNAMSIZ); | 351 | * strncpy (dev, argv[1], IFNAMSIZ); |
224 | * dev[IFNAMSIZ - 1] = '\0'; | 352 | * dev[IFNAMSIZ - 1] = '\0'; |
225 | */ | 353 | */ |
226 | /* if (-1 == (fd_tun = init_tun (dev))) | 354 | /* if (-1 == (fd_tun = init_tun (dev))) |
227 | { | ||
228 | fprintf (stderr, "Fatal: could not initialize tun-interface with IPv6 %s/%s and IPv4 %s/%s\n", | ||
229 | dev, | ||
230 | argv[2], | ||
231 | argv[3], | ||
232 | argv[4], | ||
233 | argv[5]); | ||
234 | return 1; | ||
235 | } | ||
236 | */ | ||
237 | |||
238 | if (0 != strcmp (argv[2], "-")) | ||
239 | { | ||
240 | const char *address = argv[2]; | ||
241 | long prefix_len = atol (argv[3]); | ||
242 | |||
243 | if ((prefix_len < 1) || (prefix_len > 127)) | ||
244 | { | 355 | { |
245 | fprintf (stderr, "Fatal: prefix_len out of range\n"); | 356 | fprintf (stderr, "Fatal: could not initialize tun-interface with IPv6 %s/%s and IPv4 %s/%s\n", |
357 | dev, | ||
358 | argv[2], | ||
359 | argv[3], | ||
360 | argv[4], | ||
361 | argv[5]); | ||
246 | return 1; | 362 | return 1; |
247 | } | 363 | } |
364 | */ | ||
248 | 365 | ||
249 | //set_address6 (dev, address, prefix_len); | 366 | if (0 != strcmp (argv[2], "-")) |
250 | } | 367 | { |
368 | const char *address = argv[2]; | ||
369 | long prefix_len = atol (argv[3]); | ||
370 | |||
371 | if ((prefix_len < 1) || (prefix_len > 127)) | ||
372 | { | ||
373 | fprintf (stderr, "Fatal: prefix_len out of range\n"); | ||
374 | return 1; | ||
375 | } | ||
376 | |||
377 | //set_address6 (dev, address, prefix_len); | ||
378 | } | ||
251 | 379 | ||
252 | if (0 != strcmp (argv[4], "-")) | 380 | if (0 != strcmp (argv[4], "-")) |
253 | { | 381 | { |
254 | const char *address = argv[4]; | 382 | const char *address = argv[4]; |
255 | const char *mask = argv[5]; | 383 | const char *mask = argv[5]; |
384 | |||
385 | set_address4 (NULL, address, mask); | ||
386 | } | ||
387 | |||
388 | if (setup_interface ()) | ||
389 | { | ||
390 | ; | ||
391 | } | ||
256 | 392 | ||
257 | set_address4 (NULL, address, mask); | ||
258 | } | ||
259 | |||
260 | /* | 393 | /* |
261 | uid_t uid = getuid (); | 394 | uid_t uid = getuid (); |
262 | if (0 != setresuid (uid, uid, uid)) | 395 | if (0 != setresuid (uid, uid, uid)) |
@@ -265,7 +398,7 @@ main (int argc, char **argv) | |||
265 | global_ret = 2; | 398 | global_ret = 2; |
266 | goto cleanup; | 399 | goto cleanup; |
267 | } | 400 | } |
268 | */ | 401 | */ |
269 | 402 | ||
270 | /*if (SIG_ERR == signal (SIGPIPE, SIG_IGN)) | 403 | /*if (SIG_ERR == signal (SIGPIPE, SIG_IGN)) |
271 | { | 404 | { |
@@ -273,10 +406,10 @@ main (int argc, char **argv) | |||
273 | strerror (errno)); | 406 | strerror (errno)); |
274 | // no exit, we might as well die with SIGPIPE should it ever happen | 407 | // no exit, we might as well die with SIGPIPE should it ever happen |
275 | } | 408 | } |
276 | */ | 409 | */ |
277 | //run (fd_tun); | 410 | //run (fd_tun); |
278 | global_ret = 0; | 411 | global_ret = 0; |
279 | cleanup: | 412 | cleanup: |
280 | //close (fd_tun); | 413 | //close (fd_tun); |
281 | return global_ret; | 414 | return global_ret; |
282 | } | 415 | } |