~ubuntu-branches/ubuntu/saucy/openvpn/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/kfreebsd_support.patch/tun.c

  • Committer: Package Import Robot
  • Author(s): Stéphane Graber
  • Date: 2013-05-24 17:42:45 UTC
  • mfrom: (1.1.19) (10.2.22 sid)
  • Revision ID: package-import@ubuntu.com-20130524174245-g9y6wlforycufqy5
Tags: 2.3.1-2ubuntu1
* Merge from Debian unstable. Remaining changes:
  - debian/openvpn.init.d:
    + Do not use start-stop-daemon and </dev/null to avoid blocking boot.
    + Show per-VPN result messages.
    + Add "--script-security 2" by default for backwards compatabliity.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  OpenVPN -- An application to securely tunnel IP networks
3
 
 *             over a single TCP/UDP port, with support for SSL/TLS-based
4
 
 *             session authentication and key exchange,
5
 
 *             packet encryption, packet authentication, and
6
 
 *             packet compression.
7
 
 *
8
 
 *  Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
9
 
 *
10
 
 *  This program is free software; you can redistribute it and/or modify
11
 
 *  it under the terms of the GNU General Public License version 2
12
 
 *  as published by the Free Software Foundation.
13
 
 *
14
 
 *  This program is distributed in the hope that it will be useful,
15
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
 *  GNU General Public License for more details.
18
 
 *
19
 
 *  You should have received a copy of the GNU General Public License
20
 
 *  along with this program (see the file COPYING included with this
21
 
 *  distribution); if not, write to the Free Software Foundation, Inc.,
22
 
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 
 */
24
 
 
25
 
/*
26
 
 * Support routines for configuring and accessing TUN/TAP
27
 
 * virtual network adapters.
28
 
 *
29
 
 * This file is based on the TUN/TAP driver interface routines
30
 
 * from VTun by Maxim Krasnyansky <max_mk@yahoo.com>.
31
 
 */
32
 
 
33
 
#include "syshead.h"
34
 
 
35
 
#include "tun.h"
36
 
#include "fdmisc.h"
37
 
#include "common.h"
38
 
#include "misc.h"
39
 
#include "socket.h"
40
 
#include "manage.h"
41
 
#include "route.h"
42
 
#include "win32.h"
43
 
 
44
 
#include "memdbg.h"
45
 
 
46
 
#ifdef WIN32
47
 
 
48
 
/* #define SIMULATE_DHCP_FAILED */       /* simulate bad DHCP negotiation */
49
 
 
50
 
#define NI_TEST_FIRST  (1<<0)
51
 
#define NI_IP_NETMASK  (1<<1)
52
 
#define NI_OPTIONS     (1<<2)
53
 
 
54
 
static void netsh_ifconfig (const struct tuntap_options *to,
55
 
                            const char *flex_name,
56
 
                            const in_addr_t ip,
57
 
                            const in_addr_t netmask,
58
 
                            const unsigned int flags);
59
 
static void netsh_command (const struct argv *a, int n);
60
 
 
61
 
static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc);
62
 
 
63
 
#endif
64
 
 
65
 
#ifdef TARGET_SOLARIS
66
 
static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual, bool unplumb_inet6);
67
 
#include <stropts.h>
68
 
#endif
69
 
 
70
 
bool
71
 
is_dev_type (const char *dev, const char *dev_type, const char *match_type)
72
 
{
73
 
  ASSERT (match_type);
74
 
  if (!dev)
75
 
    return false;
76
 
  if (dev_type)
77
 
    return !strcmp (dev_type, match_type);
78
 
  else
79
 
    return !strncmp (dev, match_type, strlen (match_type));
80
 
}
81
 
 
82
 
int
83
 
dev_type_enum (const char *dev, const char *dev_type)
84
 
{
85
 
  if (is_dev_type (dev, dev_type, "tun"))
86
 
    return DEV_TYPE_TUN;
87
 
  else if (is_dev_type (dev, dev_type, "tap"))
88
 
    return DEV_TYPE_TAP;
89
 
  else if (is_dev_type (dev, dev_type, "null"))
90
 
    return DEV_TYPE_NULL;
91
 
  else
92
 
    return DEV_TYPE_UNDEF;
93
 
}
94
 
 
95
 
const char *
96
 
dev_type_string (const char *dev, const char *dev_type)
97
 
{
98
 
  switch (dev_type_enum (dev, dev_type))
99
 
    {
100
 
    case DEV_TYPE_TUN:
101
 
      return "tun";
102
 
    case DEV_TYPE_TAP:
103
 
      return "tap";
104
 
    case DEV_TYPE_NULL:
105
 
      return "null";
106
 
    default:
107
 
      return "[unknown-dev-type]";
108
 
    }
109
 
}
110
 
 
111
 
/*
112
 
 * Try to predict the actual TUN/TAP device instance name,
113
 
 * before the device is actually opened.
114
 
 */
115
 
const char *
116
 
guess_tuntap_dev (const char *dev,
117
 
                  const char *dev_type,
118
 
                  const char *dev_node,
119
 
                  struct gc_arena *gc)
120
 
{
121
 
#ifdef WIN32
122
 
  const int dt = dev_type_enum (dev, dev_type);
123
 
  if (dt == DEV_TYPE_TUN || dt == DEV_TYPE_TAP)
124
 
    {
125
 
      return netsh_get_id (dev_node, gc);
126
 
    }
127
 
#endif
128
 
 
129
 
  /* default case */
130
 
  return dev;
131
 
}
132
 
 
133
 
 
134
 
/* --ifconfig-nowarn disables some options sanity checking */
135
 
static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)";
136
 
 
137
 
/*
138
 
 * If !tun, make sure ifconfig_remote_netmask looks
139
 
 *  like a netmask.
140
 
 *
141
 
 * If tun, make sure ifconfig_remote_netmask looks
142
 
 *  like an IPv4 address.
143
 
 */
144
 
static void
145
 
ifconfig_sanity_check (bool tun, in_addr_t addr, int topology)
146
 
{
147
 
  struct gc_arena gc = gc_new ();
148
 
  const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
149
 
  if (tun)
150
 
    {
151
 
      if (looks_like_netmask && (topology == TOP_NET30 || topology == TOP_P2P))
152
 
        msg (M_WARN, "WARNING: Since you are using --dev tun with a point-to-point topology, the second argument to --ifconfig must be an IP address.  You are using something (%s) that looks more like a netmask. %s",
153
 
             print_in_addr_t (addr, 0, &gc),
154
 
             ifconfig_warn_how_to_silence);
155
 
    }
156
 
  else /* tap */
157
 
    {
158
 
      if (!looks_like_netmask)
159
 
        msg (M_WARN, "WARNING: Since you are using --dev tap, the second argument to --ifconfig must be a netmask, for example something like 255.255.255.0. %s",
160
 
             ifconfig_warn_how_to_silence);
161
 
    }
162
 
  gc_free (&gc);
163
 
}
164
 
 
165
 
/*
166
 
 * For TAP-style devices, generate a broadcast address.
167
 
 */
168
 
static in_addr_t
169
 
generate_ifconfig_broadcast_addr (in_addr_t local,
170
 
                                  in_addr_t netmask)
171
 
{
172
 
  return local | ~netmask;
173
 
}
174
 
 
175
 
/*
176
 
 * Check that --local and --remote addresses do not
177
 
 * clash with ifconfig addresses or subnet.
178
 
 */
179
 
static void
180
 
check_addr_clash (const char *name,
181
 
                  int type,
182
 
                  in_addr_t public,
183
 
                  in_addr_t local,
184
 
                  in_addr_t remote_netmask)
185
 
{
186
 
  struct gc_arena gc = gc_new ();
187
 
#if 0
188
 
  msg (M_INFO, "CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
189
 
       type,
190
 
       print_in_addr_t (public, 0, &gc),
191
 
       print_in_addr_t (local, 0, &gc),
192
 
       print_in_addr_t (remote_netmask, 0, &gc));
193
 
#endif
194
 
 
195
 
  if (public)
196
 
    {
197
 
      if (type == DEV_TYPE_TUN)
198
 
        {
199
 
          const in_addr_t test_netmask = 0xFFFFFF00;
200
 
          const in_addr_t public_net = public & test_netmask;
201
 
          const in_addr_t local_net = local & test_netmask;
202
 
          const in_addr_t remote_net = remote_netmask & test_netmask;
203
 
 
204
 
          if (public == local || public == remote_netmask)
205
 
            msg (M_WARN,
206
 
                 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
207
 
                 name,
208
 
                 print_in_addr_t (public, 0, &gc),
209
 
                 print_in_addr_t (local, 0, &gc),
210
 
                 print_in_addr_t (remote_netmask, 0, &gc),
211
 
                 ifconfig_warn_how_to_silence);
212
 
 
213
 
          if (public_net == local_net || public_net == remote_net)
214
 
            msg (M_WARN,
215
 
                 "WARNING: potential conflict between --%s address [%s] and --ifconfig address pair [%s, %s] -- this is a warning only that is triggered when local/remote addresses exist within the same /24 subnet as --ifconfig endpoints. %s",
216
 
                 name,
217
 
                 print_in_addr_t (public, 0, &gc),
218
 
                 print_in_addr_t (local, 0, &gc),
219
 
                 print_in_addr_t (remote_netmask, 0, &gc),
220
 
                 ifconfig_warn_how_to_silence);
221
 
        }
222
 
      else if (type == DEV_TYPE_TAP)
223
 
        {
224
 
          const in_addr_t public_network = public & remote_netmask;
225
 
          const in_addr_t virtual_network = local & remote_netmask;
226
 
          if (public_network == virtual_network)
227
 
            msg (M_WARN,
228
 
                 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
229
 
                 name,
230
 
                 print_in_addr_t (public, 0, &gc),
231
 
                 print_in_addr_t (local, 0, &gc),
232
 
                 print_in_addr_t (remote_netmask, 0, &gc),
233
 
                 ifconfig_warn_how_to_silence);
234
 
        }
235
 
    }
236
 
  gc_free (&gc);
237
 
}
238
 
 
239
 
/*
240
 
 * Issue a warning if ip/netmask (on the virtual IP network) conflicts with
241
 
 * the settings on the local LAN.  This is designed to flag issues where
242
 
 * (for example) the OpenVPN server LAN is running on 192.168.1.x, but then
243
 
 * an OpenVPN client tries to connect from a public location that is also running
244
 
 * off of a router set to 192.168.1.x.
245
 
 */
246
 
void
247
 
check_subnet_conflict (const in_addr_t ip,
248
 
                       const in_addr_t netmask,
249
 
                       const char *prefix)
250
 
{
251
 
  struct gc_arena gc = gc_new ();
252
 
  in_addr_t lan_gw = 0;
253
 
  in_addr_t lan_netmask = 0;
254
 
 
255
 
  if (get_default_gateway (&lan_gw, &lan_netmask))
256
 
    {
257
 
      const in_addr_t lan_network = lan_gw & lan_netmask; 
258
 
      const in_addr_t network = ip & netmask;
259
 
 
260
 
      /* do the two subnets defined by network/netmask and lan_network/lan_netmask intersect? */
261
 
      if ((network & lan_netmask) == lan_network
262
 
          || (lan_network & netmask) == network)
263
 
        {
264
 
          msg (M_WARN, "WARNING: potential %s subnet conflict between local LAN [%s/%s] and remote VPN [%s/%s]",
265
 
               prefix,
266
 
               print_in_addr_t (lan_network, 0, &gc),
267
 
               print_in_addr_t (lan_netmask, 0, &gc),
268
 
               print_in_addr_t (network, 0, &gc),
269
 
               print_in_addr_t (netmask, 0, &gc));
270
 
        }
271
 
    }
272
 
  gc_free (&gc);
273
 
}
274
 
 
275
 
void
276
 
warn_on_use_of_common_subnets (void)
277
 
{
278
 
  struct gc_arena gc = gc_new ();
279
 
  in_addr_t lan_gw = 0;
280
 
  in_addr_t lan_netmask = 0;
281
 
 
282
 
  if (get_default_gateway (&lan_gw, &lan_netmask))
283
 
    {
284
 
      const in_addr_t lan_network = lan_gw & lan_netmask; 
285
 
      if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
286
 
        msg (M_WARN, "NOTE: your local LAN uses the extremely common subnet address 192.168.0.x or 192.168.1.x.  Be aware that this might create routing conflicts if you connect to the VPN server from public locations such as internet cafes that use the same subnet.");
287
 
    }
288
 
  gc_free (&gc);
289
 
}
290
 
 
291
 
/*
292
 
 * Complain if --dev tap and --ifconfig is used on an OS for which
293
 
 * we don't have a custom tap ifconfig template below.
294
 
 */
295
 
static void
296
 
no_tap_ifconfig ()
297
 
{
298
 
  msg (M_FATAL, "Sorry but you cannot use --dev tap and --ifconfig together on this OS because I have not yet been programmed to understand the appropriate ifconfig syntax to use for TAP-style devices on this OS.  Your best alternative is to use an --up script and do the ifconfig command manually.");
299
 
}
300
 
 
301
 
/*
302
 
 * Return a string to be used for options compatibility check
303
 
 * between peers.
304
 
 */
305
 
const char *
306
 
ifconfig_options_string (const struct tuntap* tt, bool remote, bool disable, struct gc_arena *gc)
307
 
{
308
 
  struct buffer out = alloc_buf_gc (256, gc);
309
 
  if (tt->did_ifconfig_setup && !disable)
310
 
    {
311
 
      if (tt->type == DEV_TYPE_TAP || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
312
 
        {
313
 
          buf_printf (&out, "%s %s",
314
 
                      print_in_addr_t (tt->local & tt->remote_netmask, 0, gc),
315
 
                      print_in_addr_t (tt->remote_netmask, 0, gc));
316
 
        }
317
 
      else if (tt->type == DEV_TYPE_TUN)
318
 
        {
319
 
          const char *l, *r;
320
 
          if (remote)
321
 
            {
322
 
              r = print_in_addr_t (tt->local, 0, gc);
323
 
              l = print_in_addr_t (tt->remote_netmask, 0, gc);
324
 
            }
325
 
          else
326
 
            {
327
 
              l = print_in_addr_t (tt->local, 0, gc);
328
 
              r = print_in_addr_t (tt->remote_netmask, 0, gc);
329
 
            }
330
 
          buf_printf (&out, "%s %s", r, l);
331
 
        }
332
 
      else
333
 
        buf_printf (&out, "[undef]");
334
 
    }
335
 
  return BSTR (&out);
336
 
}
337
 
 
338
 
/*
339
 
 * Return a status string describing wait state.
340
 
 */
341
 
const char *
342
 
tun_stat (const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc)
343
 
{
344
 
  struct buffer out = alloc_buf_gc (64, gc);
345
 
  if (tt)
346
 
    {
347
 
      if (rwflags & EVENT_READ)
348
 
        {
349
 
          buf_printf (&out, "T%s",
350
 
                      (tt->rwflags_debug & EVENT_READ) ? "R" : "r");
351
 
#ifdef WIN32
352
 
          buf_printf (&out, "%s",
353
 
                      overlapped_io_state_ascii (&tt->reads));
354
 
#endif
355
 
        }
356
 
      if (rwflags & EVENT_WRITE)
357
 
        {
358
 
          buf_printf (&out, "T%s",
359
 
                      (tt->rwflags_debug & EVENT_WRITE) ? "W" : "w");
360
 
#ifdef WIN32
361
 
          buf_printf (&out, "%s",
362
 
                      overlapped_io_state_ascii (&tt->writes));
363
 
#endif
364
 
        }
365
 
    }
366
 
  else
367
 
    {
368
 
      buf_printf (&out, "T?");
369
 
    }
370
 
  return BSTR (&out);
371
 
}
372
 
 
373
 
/*
374
 
 * Return true for point-to-point topology, false for subnet topology
375
 
 */
376
 
bool
377
 
is_tun_p2p (const struct tuntap *tt)
378
 
{
379
 
  bool tun = false;
380
 
 
381
 
  if (tt->type == DEV_TYPE_TAP || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
382
 
    tun = false;
383
 
  else if (tt->type == DEV_TYPE_TUN)
384
 
    tun = true;
385
 
  else
386
 
    msg (M_FATAL, "Error: problem with tun vs. tap setting"); /* JYFIXME -- needs to be caught earlier, in init_tun? */
387
 
 
388
 
  return tun;
389
 
}
390
 
 
391
 
/*
392
 
 * Init tun/tap object.
393
 
 *
394
 
 * Set up tuntap structure for ifconfig,
395
 
 * but don't execute yet.
396
 
 */
397
 
struct tuntap *
398
 
init_tun (const char *dev,       /* --dev option */
399
 
          const char *dev_type,  /* --dev-type option */
400
 
          int topology,          /* one of the TOP_x values */
401
 
          const char *ifconfig_local_parm,          /* --ifconfig parm 1 */
402
 
          const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
403
 
          const char *ifconfig_ipv6_local_parm,     /* --ifconfig parm 1 IPv6 */
404
 
          const char *ifconfig_ipv6_remote_parm,    /* --ifconfig parm 2 IPv6 */
405
 
          in_addr_t local_public,
406
 
          in_addr_t remote_public,
407
 
          const bool strict_warn,
408
 
          struct env_set *es)
409
 
{
410
 
  struct gc_arena gc = gc_new ();
411
 
  struct tuntap *tt;
412
 
 
413
 
  ALLOC_OBJ (tt, struct tuntap);
414
 
  clear_tuntap (tt);
415
 
 
416
 
  tt->type = dev_type_enum (dev, dev_type);
417
 
  tt->topology = topology;
418
 
 
419
 
  if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
420
 
    {
421
 
      bool tun = false;
422
 
      const char *ifconfig_local = NULL;
423
 
      const char *ifconfig_remote_netmask = NULL;
424
 
      const char *ifconfig_broadcast = NULL;
425
 
 
426
 
      /*
427
 
       * We only handle TUN/TAP devices here, not --dev null devices.
428
 
       */
429
 
      tun = is_tun_p2p (tt);
430
 
 
431
 
      /*
432
 
       * Convert arguments to binary IPv4 addresses.
433
 
       */
434
 
 
435
 
      tt->local = getaddr (
436
 
                           GETADDR_RESOLVE
437
 
                           | GETADDR_HOST_ORDER
438
 
                           | GETADDR_FATAL_ON_SIGNAL
439
 
                           | GETADDR_FATAL,
440
 
                           ifconfig_local_parm,
441
 
                           0,
442
 
                           NULL,
443
 
                           NULL);
444
 
 
445
 
      tt->remote_netmask = getaddr (
446
 
                                    (tun ? GETADDR_RESOLVE : 0)
447
 
                                    | GETADDR_HOST_ORDER
448
 
                                    | GETADDR_FATAL_ON_SIGNAL
449
 
                                    | GETADDR_FATAL,
450
 
                                    ifconfig_remote_netmask_parm,
451
 
                                    0,
452
 
                                    NULL,
453
 
                                    NULL);
454
 
 
455
 
      /*
456
 
       * Look for common errors in --ifconfig parms
457
 
       */
458
 
      if (strict_warn)
459
 
        {
460
 
          ifconfig_sanity_check (tt->type == DEV_TYPE_TUN, tt->remote_netmask, tt->topology);
461
 
 
462
 
          /*
463
 
           * If local_public or remote_public addresses are defined,
464
 
           * make sure they do not clash with our virtual subnet.
465
 
           */
466
 
 
467
 
          check_addr_clash ("local",
468
 
                            tt->type,
469
 
                            local_public,
470
 
                            tt->local,
471
 
                            tt->remote_netmask);
472
 
 
473
 
          check_addr_clash ("remote",
474
 
                            tt->type,
475
 
                            remote_public,
476
 
                            tt->local,
477
 
                            tt->remote_netmask);
478
 
 
479
 
          if (tt->type == DEV_TYPE_TAP || (tt->type == DEV_TYPE_TUN && tt->topology == TOP_SUBNET))
480
 
            check_subnet_conflict (tt->local, tt->remote_netmask, "TUN/TAP adapter");
481
 
          else if (tt->type == DEV_TYPE_TUN)
482
 
            check_subnet_conflict (tt->local, ~0, "TUN/TAP adapter");
483
 
        }
484
 
 
485
 
      /*
486
 
       * Set ifconfig parameters
487
 
       */
488
 
      ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
489
 
      ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
490
 
 
491
 
      /*
492
 
       * If TAP-style interface, generate broadcast address.
493
 
       */
494
 
      if (!tun)
495
 
        {
496
 
          tt->broadcast = generate_ifconfig_broadcast_addr (tt->local, tt->remote_netmask);
497
 
          ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc);
498
 
        }
499
 
 
500
 
      /*
501
 
       * Set environmental variables with ifconfig parameters.
502
 
       */
503
 
      if (es)
504
 
        {
505
 
          setenv_str (es, "ifconfig_local", ifconfig_local);
506
 
          if (tun)
507
 
            {
508
 
              setenv_str (es, "ifconfig_remote", ifconfig_remote_netmask);
509
 
            }
510
 
          else
511
 
            {
512
 
              setenv_str (es, "ifconfig_netmask", ifconfig_remote_netmask);
513
 
              setenv_str (es, "ifconfig_broadcast", ifconfig_broadcast);
514
 
            }
515
 
        }
516
 
 
517
 
      tt->did_ifconfig_setup = true;
518
 
    }
519
 
 
520
 
  if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
521
 
    {
522
 
      const char *ifconfig_ipv6_local = NULL;
523
 
      const char *ifconfig_ipv6_remote = NULL;
524
 
 
525
 
      /*
526
 
       * Convert arguments to binary IPv6 addresses.
527
 
       */
528
 
 
529
 
      if ( inet_pton( AF_INET6, ifconfig_ipv6_local_parm, &tt->local_ipv6 ) != 1 ||
530
 
           inet_pton( AF_INET6, ifconfig_ipv6_remote_parm, &tt->remote_ipv6 ) != 1 ) 
531
 
        {
532
 
          msg( M_FATAL, "init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm );
533
 
        }
534
 
      tt->netbits_ipv6 = 64;
535
 
 
536
 
      /*
537
 
       * Set ifconfig parameters
538
 
       */
539
 
      ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
540
 
      ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc);
541
 
 
542
 
      /*
543
 
       * Set environmental variables with ifconfig parameters.
544
 
       */
545
 
      if (es)
546
 
        {
547
 
          setenv_str (es, "ifconfig_ipv6_local", ifconfig_ipv6_local);
548
 
          setenv_str (es, "ifconfig_ipv6_remote", ifconfig_ipv6_remote);
549
 
        }
550
 
      tt->did_ifconfig_ipv6_setup = true;
551
 
    }
552
 
 
553
 
  gc_free (&gc);
554
 
  return tt;
555
 
}
556
 
 
557
 
/*
558
 
 * Platform specific tun initializations
559
 
 */
560
 
void
561
 
init_tun_post (struct tuntap *tt,
562
 
               const struct frame *frame,
563
 
               const struct tuntap_options *options)
564
 
{
565
 
  tt->options = *options;
566
 
#ifdef WIN32
567
 
  overlapped_io_init (&tt->reads, frame, FALSE, true);
568
 
  overlapped_io_init (&tt->writes, frame, TRUE, true);
569
 
  tt->rw_handle.read = tt->reads.overlapped.hEvent;
570
 
  tt->rw_handle.write = tt->writes.overlapped.hEvent;
571
 
  tt->adapter_index = ~0;
572
 
#endif
573
 
}
574
 
 
575
 
#if defined(TARGET_WIN32) || \
576
 
    defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD)
577
 
 
578
 
/* some of the platforms will auto-add a "network route" pointing
579
 
 * to the interface on "ifconfig tunX 2001:db8::1/64", others need
580
 
 * an extra call to "route add..."
581
 
 * -> helper function to simplify code below
582
 
 */
583
 
void add_route_connected_v6_net(struct tuntap * tt,
584
 
                                const struct env_set *es)
585
 
{
586
 
    struct route_ipv6 r6;
587
 
 
588
 
    r6.defined = true;
589
 
    r6.network = tt->local_ipv6;
590
 
    r6.netbits = tt->netbits_ipv6;
591
 
    r6.gateway = tt->local_ipv6;
592
 
    add_route_ipv6 (&r6, tt, 0, es);
593
 
}
594
 
#endif
595
 
 
596
 
 
597
 
/* execute the ifconfig command through the shell */
598
 
void
599
 
do_ifconfig (struct tuntap *tt,
600
 
             const char *actual,    /* actual device name */
601
 
             int tun_mtu,
602
 
             const struct env_set *es)
603
 
{
604
 
  struct gc_arena gc = gc_new ();
605
 
 
606
 
  if (tt->did_ifconfig_setup)
607
 
    {
608
 
      bool tun = false;
609
 
      const char *ifconfig_local = NULL;
610
 
      const char *ifconfig_remote_netmask = NULL;
611
 
      const char *ifconfig_broadcast = NULL;
612
 
      const char *ifconfig_ipv6_local = NULL;
613
 
      const char *ifconfig_ipv6_remote = NULL;
614
 
      bool do_ipv6 = false;
615
 
      struct argv argv;
616
 
 
617
 
      argv_init (&argv);
618
 
 
619
 
      msg( M_INFO, "do_ifconfig, tt->ipv6=%d, tt->did_ifconfig_ipv6_setup=%d",
620
 
                   tt->ipv6, tt->did_ifconfig_ipv6_setup );
621
 
 
622
 
      /*
623
 
       * We only handle TUN/TAP devices here, not --dev null devices.
624
 
       */
625
 
      tun = is_tun_p2p (tt);
626
 
 
627
 
      /*
628
 
       * Set ifconfig parameters
629
 
       */
630
 
      ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
631
 
      ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
632
 
 
633
 
      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
634
 
        {
635
 
          ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
636
 
          ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc);
637
 
          do_ipv6 = true;
638
 
        }
639
 
 
640
 
      /*
641
 
       * If TAP-style device, generate broadcast address.
642
 
       */
643
 
      if (!tun)
644
 
        ifconfig_broadcast = print_in_addr_t (tt->broadcast, 0, &gc);
645
 
 
646
 
#ifdef ENABLE_MANAGEMENT
647
 
  if (management)
648
 
    {
649
 
      management_set_state (management,
650
 
                            OPENVPN_STATE_ASSIGN_IP,
651
 
                            NULL,
652
 
                            tt->local,
653
 
                            0);
654
 
    }
655
 
#endif
656
 
 
657
 
 
658
 
#if defined(TARGET_LINUX)
659
 
#ifdef CONFIG_FEATURE_IPROUTE
660
 
        /*
661
 
         * Set the MTU for the device
662
 
         */
663
 
        argv_printf (&argv,
664
 
                          "%s link set dev %s up mtu %d",
665
 
                          iproute_path,
666
 
                          actual,
667
 
                          tun_mtu
668
 
                          );
669
 
          argv_msg (M_INFO, &argv);
670
 
          openvpn_execve_check (&argv, es, S_FATAL, "Linux ip link set failed");
671
 
 
672
 
        if (tun) {
673
 
 
674
 
                /*
675
 
                 * Set the address for the device
676
 
                 */
677
 
                argv_printf (&argv,
678
 
                                  "%s addr add dev %s local %s peer %s",
679
 
                                  iproute_path,
680
 
                                  actual,
681
 
                                  ifconfig_local,
682
 
                                  ifconfig_remote_netmask
683
 
                                  );
684
 
                  argv_msg (M_INFO, &argv);
685
 
                  openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed");
686
 
        } else {
687
 
                argv_printf (&argv,
688
 
                                  "%s addr add dev %s %s/%d broadcast %s",
689
 
                                  iproute_path,
690
 
                                  actual,
691
 
                                  ifconfig_local,
692
 
                                  count_netmask_bits(ifconfig_remote_netmask),
693
 
                                  ifconfig_broadcast
694
 
                                  );
695
 
                  argv_msg (M_INFO, &argv);
696
 
                  openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed");
697
 
        }
698
 
      if ( do_ipv6 )
699
 
        {
700
 
          argv_printf( &argv,
701
 
                      "%s -6 addr add %s/%d dev %s",
702
 
                      iproute_path,
703
 
                      ifconfig_ipv6_local,
704
 
                      tt->netbits_ipv6,
705
 
                      actual
706
 
                      );
707
 
          argv_msg (M_INFO, &argv);
708
 
          openvpn_execve_check (&argv, es, S_FATAL, "Linux ip -6 addr add failed");
709
 
        }
710
 
      tt->did_ifconfig = true;
711
 
#else
712
 
      if (tun)
713
 
        argv_printf (&argv,
714
 
                          "%s %s %s pointopoint %s mtu %d",
715
 
                          IFCONFIG_PATH,
716
 
                          actual,
717
 
                          ifconfig_local,
718
 
                          ifconfig_remote_netmask,
719
 
                          tun_mtu
720
 
                          );
721
 
      else
722
 
        argv_printf (&argv,
723
 
                          "%s %s %s netmask %s mtu %d broadcast %s",
724
 
                          IFCONFIG_PATH,
725
 
                          actual,
726
 
                          ifconfig_local,
727
 
                          ifconfig_remote_netmask,
728
 
                          tun_mtu,
729
 
                          ifconfig_broadcast
730
 
                          );
731
 
      argv_msg (M_INFO, &argv);
732
 
      openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig failed");
733
 
      if ( do_ipv6 )
734
 
        {
735
 
          argv_printf (&argv,
736
 
                          "%s %s inet6 add %s/%d",
737
 
                          IFCONFIG_PATH,
738
 
                          actual,
739
 
                          ifconfig_ipv6_local,
740
 
                          tt->netbits_ipv6
741
 
                          );
742
 
          argv_msg (M_INFO, &argv);
743
 
          openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
744
 
        }
745
 
      tt->did_ifconfig = true;
746
 
 
747
 
#endif /*CONFIG_FEATURE_IPROUTE*/
748
 
#elif defined(TARGET_SOLARIS)
749
 
 
750
 
      /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
751
 
       * example:
752
 
       *    ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 up
753
 
       *    ifconfig tun2 netmask 255.255.255.255
754
 
       */
755
 
      if (tun)
756
 
        {
757
 
          argv_printf (&argv,
758
 
                            "%s %s %s %s mtu %d up",
759
 
                            IFCONFIG_PATH,
760
 
                            actual,
761
 
                            ifconfig_local,
762
 
                            ifconfig_remote_netmask,
763
 
                            tun_mtu
764
 
                            );
765
 
 
766
 
          argv_msg (M_INFO, &argv);
767
 
          if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-1 failed"))
768
 
            solaris_error_close (tt, es, actual, false);
769
 
 
770
 
          argv_printf (&argv,
771
 
                            "%s %s netmask 255.255.255.255",
772
 
                            IFCONFIG_PATH,
773
 
                            actual
774
 
                            );
775
 
        }
776
 
      else
777
 
        if (tt->topology == TOP_SUBNET)
778
 
        {
779
 
          argv_printf (&argv,
780
 
                              "%s %s %s %s netmask %s mtu %d up",
781
 
                              IFCONFIG_PATH,
782
 
                              actual,
783
 
                              ifconfig_local,
784
 
                              ifconfig_local,
785
 
                              ifconfig_remote_netmask,
786
 
                              tun_mtu
787
 
                              );
788
 
        }
789
 
        else
790
 
          argv_printf (&argv,
791
 
                            " %s %s %s netmask %s broadcast + up",
792
 
                            IFCONFIG_PATH,
793
 
                            actual,
794
 
                            ifconfig_local,
795
 
                            ifconfig_remote_netmask
796
 
                            );
797
 
 
798
 
      argv_msg (M_INFO, &argv);
799
 
      if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed"))
800
 
        solaris_error_close (tt, es, actual, false);
801
 
 
802
 
      if ( do_ipv6 )
803
 
        {
804
 
          argv_printf (&argv, "%s %s inet6 unplumb",
805
 
                            IFCONFIG_PATH, actual );
806
 
          argv_msg (M_INFO, &argv);
807
 
          openvpn_execve_check (&argv, es, 0, NULL);
808
 
 
809
 
          if ( tt->type == DEV_TYPE_TUN )
810
 
           {
811
 
              argv_printf (&argv,
812
 
                            "%s %s inet6 plumb %s/%d %s up",
813
 
                            IFCONFIG_PATH,
814
 
                            actual,
815
 
                            ifconfig_ipv6_local,
816
 
                            tt->netbits_ipv6,
817
 
                            ifconfig_ipv6_remote
818
 
                            );
819
 
            }
820
 
          else                                          /* tap mode */
821
 
            {
822
 
              /* base IPv6 tap interface needs to be brought up first
823
 
               */
824
 
              argv_printf (&argv, "%s %s inet6 plumb up",
825
 
                            IFCONFIG_PATH, actual );
826
 
              argv_msg (M_INFO, &argv);
827
 
              if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed"))
828
 
                solaris_error_close (tt, es, actual, true);
829
 
 
830
 
              /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
831
 
               * after the system has noticed the interface and fired up
832
 
               * the DHCPv6 client - but this takes quite a while, and the 
833
 
               * server will ignore the DHCPv6 packets anyway.  So we don't.
834
 
               */
835
 
 
836
 
              /* static IPv6 addresses need to go to a subinterface (tap0:1)
837
 
               */
838
 
              argv_printf (&argv,
839
 
                            "%s %s inet6 addif %s/%d up",
840
 
                            IFCONFIG_PATH, actual,
841
 
                            ifconfig_ipv6_local, tt->netbits_ipv6 );
842
 
            }
843
 
          argv_msg (M_INFO, &argv);
844
 
          if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 failed"))
845
 
            solaris_error_close (tt, es, actual, true);
846
 
        }
847
 
 
848
 
      if (!tun && tt->topology == TOP_SUBNET)
849
 
        {
850
 
          /* Add a network route for the local tun interface */
851
 
          struct route r;
852
 
          CLEAR (r);      
853
 
          r.defined = true;       
854
 
          r.network = tt->local & tt->remote_netmask;
855
 
          r.netmask = tt->remote_netmask;
856
 
          r.gateway = tt->local;  
857
 
          r.metric_defined = true;
858
 
          r.metric = 0;
859
 
          add_route (&r, tt, 0, es);
860
 
        }
861
 
 
862
 
      tt->did_ifconfig = true;
863
 
 
864
 
#elif defined(TARGET_OPENBSD)
865
 
 
866
 
      /*
867
 
       * OpenBSD tun devices appear to be persistent by default.  It seems in order
868
 
       * to make this work correctly, we need to delete the previous instance
869
 
       * (if it exists), and re-ifconfig.  Let me know if you know a better way.
870
 
       */
871
 
 
872
 
      argv_printf (&argv,
873
 
                        "%s %s destroy",
874
 
                        IFCONFIG_PATH,
875
 
                        actual);
876
 
      argv_msg (M_INFO, &argv);
877
 
      openvpn_execve_check (&argv, es, 0, NULL);
878
 
      argv_printf (&argv,
879
 
                        "%s %s create",
880
 
                        IFCONFIG_PATH,
881
 
                        actual);
882
 
      argv_msg (M_INFO, &argv);
883
 
      openvpn_execve_check (&argv, es, 0, NULL);
884
 
      msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
885
 
 
886
 
      /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
887
 
      if (tun)
888
 
        argv_printf (&argv,
889
 
                          "%s %s %s %s mtu %d netmask 255.255.255.255 up",
890
 
                          IFCONFIG_PATH,
891
 
                          actual,
892
 
                          ifconfig_local,
893
 
                          ifconfig_remote_netmask,
894
 
                          tun_mtu
895
 
                          );
896
 
      else
897
 
        argv_printf (&argv,
898
 
                          "%s %s %s netmask %s mtu %d broadcast %s link0",
899
 
                          IFCONFIG_PATH,
900
 
                          actual,
901
 
                          ifconfig_local,
902
 
                          ifconfig_remote_netmask,
903
 
                          tun_mtu,
904
 
                          ifconfig_broadcast
905
 
                          );
906
 
      argv_msg (M_INFO, &argv);
907
 
      openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig failed");
908
 
      if ( do_ipv6 )
909
 
        {
910
 
          argv_printf (&argv,
911
 
                          "%s %s inet6 %s/%d",
912
 
                          IFCONFIG_PATH,
913
 
                          actual,
914
 
                          ifconfig_ipv6_local,
915
 
                          tt->netbits_ipv6
916
 
                          );
917
 
          argv_msg (M_INFO, &argv);
918
 
          openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed");
919
 
 
920
 
          /* and, hooray, we explicitely need to add a route... */
921
 
          add_route_connected_v6_net(tt, es);
922
 
        }
923
 
      tt->did_ifconfig = true;
924
 
 
925
 
#elif defined(TARGET_NETBSD)
926
 
 
927
 
/* whether or not NetBSD can do IPv6 can be seen by the availability of
928
 
 * the TUNSIFHEAD ioctl() - see next TARGET_NETBSD block for more details
929
 
 */
930
 
#ifdef TUNSIFHEAD
931
 
# define NETBSD_MULTI_AF
932
 
#endif
933
 
 
934
 
      /* as on OpenBSD and Darwin, destroy and re-create tun<x> interface
935
 
       */
936
 
      argv_printf (&argv, "%s %s destroy", IFCONFIG_PATH, actual );
937
 
      argv_msg (M_INFO, &argv);
938
 
      openvpn_execve_check (&argv, es, 0, "NetBSD ifconfig destroy failed");
939
 
 
940
 
      argv_printf (&argv, "%s %s create", IFCONFIG_PATH, actual );
941
 
      argv_msg (M_INFO, &argv);
942
 
      openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig create failed");
943
 
 
944
 
      if (tun)
945
 
        argv_printf (&argv,
946
 
                          "%s %s %s %s mtu %d netmask 255.255.255.255 up",
947
 
                          IFCONFIG_PATH,
948
 
                          actual,
949
 
                          ifconfig_local,
950
 
                          ifconfig_remote_netmask,
951
 
                          tun_mtu
952
 
                          );
953
 
      else
954
 
      /*
955
 
       * NetBSD has distinct tun and tap devices
956
 
       * so we don't need the "link0" extra parameter to specify we want to do 
957
 
       * tunneling at the ethernet level
958
 
       */
959
 
                argv_printf (&argv,
960
 
                          "%s %s %s netmask %s mtu %d broadcast %s",
961
 
                          IFCONFIG_PATH,
962
 
                          actual,
963
 
                          ifconfig_local,
964
 
                          ifconfig_remote_netmask,
965
 
                          tun_mtu,
966
 
                          ifconfig_broadcast
967
 
                          );
968
 
      argv_msg (M_INFO, &argv);
969
 
      openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig failed");
970
 
 
971
 
      if ( do_ipv6 )
972
 
        {
973
 
#ifdef NETBSD_MULTI_AF
974
 
          argv_printf (&argv,
975
 
                          "%s %s inet6 %s/%d",
976
 
                          IFCONFIG_PATH,
977
 
                          actual,
978
 
                          ifconfig_ipv6_local,
979
 
                          tt->netbits_ipv6
980
 
                          );
981
 
          argv_msg (M_INFO, &argv);
982
 
          openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed");
983
 
 
984
 
          /* and, hooray, we explicitely need to add a route... */
985
 
          add_route_connected_v6_net(tt, es);
986
 
#else
987
 
          msg( M_INFO, "no IPv6 support for tun interfaces on NetBSD before 4.0 (if your system is newer, recompile openvpn)" );
988
 
          tt->ipv6 = false;
989
 
#endif
990
 
        }
991
 
      tt->did_ifconfig = true;
992
 
 
993
 
#elif defined(TARGET_DARWIN)
994
 
 
995
 
      /*
996
 
       * Darwin (i.e. Mac OS X) seems to exhibit similar behaviour to OpenBSD...
997
 
       */
998
 
 
999
 
      argv_printf (&argv,
1000
 
                        "%s %s delete",
1001
 
                        IFCONFIG_PATH,
1002
 
                        actual);
1003
 
      argv_msg (M_INFO, &argv);
1004
 
      openvpn_execve_check (&argv, es, 0, NULL);
1005
 
      msg (M_INFO, "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1006
 
 
1007
 
 
1008
 
      /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1009
 
      if (tun)
1010
 
        argv_printf (&argv,
1011
 
                          "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1012
 
                          IFCONFIG_PATH,
1013
 
                          actual,
1014
 
                          ifconfig_local,
1015
 
                          ifconfig_remote_netmask,
1016
 
                          tun_mtu
1017
 
                          );
1018
 
      else
1019
 
        {
1020
 
          if (tt->topology == TOP_SUBNET)
1021
 
            argv_printf (&argv,
1022
 
                              "%s %s %s %s netmask %s mtu %d up",
1023
 
                              IFCONFIG_PATH,
1024
 
                              actual,
1025
 
                              ifconfig_local,
1026
 
                              ifconfig_local,
1027
 
                              ifconfig_remote_netmask,
1028
 
                              tun_mtu
1029
 
                              );
1030
 
          else
1031
 
            argv_printf (&argv,
1032
 
                              "%s %s %s netmask %s mtu %d up",
1033
 
                              IFCONFIG_PATH,
1034
 
                              actual,
1035
 
                              ifconfig_local,
1036
 
                              ifconfig_remote_netmask,
1037
 
                              tun_mtu
1038
 
                              );
1039
 
        }
1040
 
      argv_msg (M_INFO, &argv);
1041
 
      openvpn_execve_check (&argv, es, S_FATAL, "Mac OS X ifconfig failed");
1042
 
      tt->did_ifconfig = true;
1043
 
 
1044
 
      /* Add a network route for the local tun interface */
1045
 
      if (!tun && tt->topology == TOP_SUBNET)
1046
 
        {
1047
 
          struct route r;
1048
 
          CLEAR (r);
1049
 
          r.defined = true;
1050
 
          r.network = tt->local & tt->remote_netmask;
1051
 
          r.netmask = tt->remote_netmask;
1052
 
          r.gateway = tt->local;
1053
 
          add_route (&r, tt, 0, es);
1054
 
        }
1055
 
 
1056
 
      if ( do_ipv6 )
1057
 
        {
1058
 
          argv_printf (&argv,
1059
 
                              "%s %s inet6 %s/%d",
1060
 
                              IFCONFIG_PATH,
1061
 
                              actual,
1062
 
                              ifconfig_ipv6_local,
1063
 
                              tt->netbits_ipv6
1064
 
                              );
1065
 
          argv_msg (M_INFO, &argv);
1066
 
          openvpn_execve_check (&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed");
1067
 
 
1068
 
          /* and, hooray, we explicitely need to add a route... */
1069
 
          add_route_connected_v6_net(tt, es);
1070
 
        }
1071
 
 
1072
 
#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
1073
 
 
1074
 
      /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1075
 
      if (tun)
1076
 
        argv_printf (&argv,
1077
 
                          "%s %s %s %s mtu %d netmask 255.255.255.255 up",
1078
 
                          IFCONFIG_PATH,
1079
 
                          actual,
1080
 
                          ifconfig_local,
1081
 
                          ifconfig_remote_netmask,
1082
 
                          tun_mtu
1083
 
                          );
1084
 
      else
1085
 
        argv_printf (&argv,
1086
 
                      "%s %s %s netmask %s mtu %d up",
1087
 
                              IFCONFIG_PATH,
1088
 
                              actual,
1089
 
                              ifconfig_local,
1090
 
                              ifconfig_remote_netmask,
1091
 
                              tun_mtu
1092
 
                              );
1093
 
        
1094
 
      argv_msg (M_INFO, &argv);
1095
 
      openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig failed");
1096
 
      tt->did_ifconfig = true;
1097
 
 
1098
 
        /* Add a network route for the local tun interface */
1099
 
      if (!tun && tt->topology == TOP_SUBNET)
1100
 
        {               
1101
 
          struct route r;
1102
 
          CLEAR (r);      
1103
 
          r.defined = true;       
1104
 
          r.network = tt->local & tt->remote_netmask;
1105
 
          r.netmask = tt->remote_netmask;
1106
 
          r.gateway = tt->local;  
1107
 
          add_route (&r, tt, 0, es);
1108
 
        }
1109
 
 
1110
 
      if ( do_ipv6 )
1111
 
        {
1112
 
          argv_printf (&argv,
1113
 
                              "%s %s inet6 %s/%d",
1114
 
                              IFCONFIG_PATH,
1115
 
                              actual,
1116
 
                              ifconfig_ipv6_local,
1117
 
                              tt->netbits_ipv6
1118
 
                              );
1119
 
          argv_msg (M_INFO, &argv);
1120
 
          openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
1121
 
        }
1122
 
 
1123
 
#elif defined (WIN32)
1124
 
      {
1125
 
        /*
1126
 
         * Make sure that both ifconfig addresses are part of the
1127
 
         * same .252 subnet.
1128
 
         */
1129
 
        if (tun)
1130
 
          {
1131
 
            verify_255_255_255_252 (tt->local, tt->remote_netmask);
1132
 
            tt->adapter_netmask = ~3;
1133
 
          }
1134
 
        else
1135
 
          {
1136
 
            tt->adapter_netmask = tt->remote_netmask;
1137
 
          }
1138
 
 
1139
 
        switch (tt->options.ip_win32_type)
1140
 
          {
1141
 
          case IPW32_SET_MANUAL:
1142
 
            msg (M_INFO, "******** NOTE:  Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1143
 
                 actual,
1144
 
                 ifconfig_local,
1145
 
                 print_in_addr_t (tt->adapter_netmask, 0, &gc));
1146
 
            break;
1147
 
          case IPW32_SET_NETSH:
1148
 
            if (!strcmp (actual, "NULL"))
1149
 
              msg (M_FATAL, "Error: When using --ip-win32 netsh, if you have more than one TAP-Win32 adapter, you must also specify --dev-node");
1150
 
 
1151
 
            netsh_ifconfig (&tt->options,
1152
 
                            actual,
1153
 
                            tt->local,
1154
 
                            tt->adapter_netmask,
1155
 
                            NI_IP_NETMASK|NI_OPTIONS);
1156
 
 
1157
 
            break;
1158
 
          }
1159
 
        tt->did_ifconfig = true;
1160
 
      }
1161
 
 
1162
 
    /* IPv6 always uses "netsh" interface */
1163
 
    if ( do_ipv6 )
1164
 
      {
1165
 
        char * saved_actual;
1166
 
 
1167
 
        if (!strcmp (actual, "NULL"))
1168
 
          msg (M_FATAL, "Error: When using --tun-ipv6, if you have more than one TAP-Win32 adapter, you must also specify --dev-node");
1169
 
 
1170
 
        /* example: netsh interface ipv6 add address MyTap 2001:608:8003::d */
1171
 
        argv_printf (&argv,
1172
 
                    "%s%sc interface ipv6 add address %s %s",
1173
 
                     get_win_sys_path(),
1174
 
                     NETSH_PATH_SUFFIX,
1175
 
                     actual,
1176
 
                     ifconfig_ipv6_local );
1177
 
 
1178
 
        netsh_command (&argv, 4);
1179
 
 
1180
 
        /* explicit route needed */
1181
 
        /* on windows, OpenVPN does ifconfig first, open_tun later, so
1182
 
         * tt->actual_name might not yet be initialized, but routing code
1183
 
         * needs to know interface name - point to "actual", restore later
1184
 
         */
1185
 
        saved_actual = tt->actual_name;
1186
 
        tt->actual_name = (char*) actual;
1187
 
        add_route_connected_v6_net(tt, es);
1188
 
        tt->actual_name = saved_actual;
1189
 
      }
1190
 
#else
1191
 
      msg (M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system.  You should ifconfig your TUN/TAP device manually or use an --up script.");
1192
 
#endif
1193
 
      argv_reset (&argv);
1194
 
    }
1195
 
  gc_free (&gc);
1196
 
}
1197
 
 
1198
 
void
1199
 
clear_tuntap (struct tuntap *tuntap)
1200
 
{
1201
 
  CLEAR (*tuntap);
1202
 
#ifdef WIN32
1203
 
  tuntap->hand = NULL;
1204
 
#else
1205
 
  tuntap->fd = -1;
1206
 
#endif
1207
 
#ifdef TARGET_SOLARIS
1208
 
  tuntap->ip_fd = -1;
1209
 
#endif
1210
 
  tuntap->ipv6 = false;
1211
 
}
1212
 
 
1213
 
static void
1214
 
open_null (struct tuntap *tt)
1215
 
{
1216
 
  tt->actual_name = string_alloc ("null", NULL);
1217
 
}
1218
 
 
1219
 
#ifndef WIN32
1220
 
static void
1221
 
open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
1222
 
                  bool ipv6_explicitly_supported, bool dynamic,
1223
 
                  struct tuntap *tt)
1224
 
{
1225
 
  char tunname[256];
1226
 
  char dynamic_name[256];
1227
 
  bool dynamic_opened = false;
1228
 
 
1229
 
 
1230
 
  if ( tt->ipv6 && ! ipv6_explicitly_supported )
1231
 
    msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
1232
 
 
1233
 
  if (tt->type == DEV_TYPE_NULL)
1234
 
    {
1235
 
      open_null (tt);
1236
 
    }
1237
 
  else
1238
 
    {
1239
 
      /*
1240
 
       * --dev-node specified, so open an explicit device node
1241
 
       */
1242
 
      if (dev_node)
1243
 
        {
1244
 
          openvpn_snprintf (tunname, sizeof (tunname), "%s", dev_node);
1245
 
        }
1246
 
      else
1247
 
        {
1248
 
          /*
1249
 
           * dynamic open is indicated by --dev specified without
1250
 
           * explicit unit number.  Try opening /dev/[dev]n
1251
 
           * where n = [0, 255].
1252
 
           */
1253
 
          if (dynamic && !has_digit((unsigned char *)dev))
1254
 
            {
1255
 
              int i;
1256
 
              for (i = 0; i < 256; ++i)
1257
 
                {
1258
 
                  openvpn_snprintf (tunname, sizeof (tunname),
1259
 
                                    "/dev/%s%d", dev, i);
1260
 
                  openvpn_snprintf (dynamic_name, sizeof (dynamic_name),
1261
 
                                    "%s%d", dev, i);
1262
 
                  if ((tt->fd = open (tunname, O_RDWR)) > 0)
1263
 
                    {
1264
 
                      dynamic_opened = true;
1265
 
                      break;
1266
 
                    }
1267
 
                  msg (D_READ_WRITE | M_ERRNO, "Tried opening %s (failed)", tunname);
1268
 
                }
1269
 
              if (!dynamic_opened)
1270
 
                msg (M_FATAL, "Cannot allocate TUN/TAP dev dynamically");
1271
 
            }
1272
 
          /*
1273
 
           * explicit unit number specified
1274
 
           */
1275
 
          else
1276
 
            {
1277
 
              openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dev);
1278
 
            }
1279
 
        }
1280
 
 
1281
 
      if (!dynamic_opened)
1282
 
        {
1283
 
          if ((tt->fd = open (tunname, O_RDWR)) < 0)
1284
 
            msg (M_ERR, "Cannot open TUN/TAP dev %s", tunname);
1285
 
        }
1286
 
 
1287
 
      set_nonblock (tt->fd);
1288
 
      set_cloexec (tt->fd); /* don't pass fd to scripts */
1289
 
      msg (M_INFO, "TUN/TAP device %s opened", tunname);
1290
 
 
1291
 
      /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
1292
 
      tt->actual_name = string_alloc (dynamic_opened ? dynamic_name : dev, NULL);
1293
 
    }
1294
 
}
1295
 
 
1296
 
static void
1297
 
close_tun_generic (struct tuntap *tt)
1298
 
{
1299
 
  if (tt->fd >= 0)
1300
 
    close (tt->fd);
1301
 
  if (tt->actual_name)
1302
 
    free (tt->actual_name);
1303
 
  clear_tuntap (tt);
1304
 
}
1305
 
 
1306
 
#endif
1307
 
 
1308
 
#if defined(TARGET_LINUX)
1309
 
 
1310
 
#ifdef HAVE_LINUX_IF_TUN_H      /* New driver support */
1311
 
 
1312
 
#ifndef HAVE_LINUX_SOCKIOS_H
1313
 
#error header file linux/sockios.h required
1314
 
#endif
1315
 
 
1316
 
#if defined(HAVE_TUN_PI) && defined(HAVE_IPHDR) && defined(HAVE_IOVEC) && defined(ETH_P_IPV6) && defined(ETH_P_IP) && defined(HAVE_READV) && defined(HAVE_WRITEV)
1317
 
#define LINUX_IPV6 1
1318
 
/* #warning IPv6 ON */
1319
 
#else
1320
 
#define LINUX_IPV6 0
1321
 
/* #warning IPv6 OFF */
1322
 
#endif
1323
 
 
1324
 
#if !PEDANTIC
1325
 
 
1326
 
void
1327
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1328
 
{
1329
 
  struct ifreq ifr;
1330
 
 
1331
 
  /* warn if a very old linux version is used & --tun-ipv6 set
1332
 
   */
1333
 
#if LINUX_IPV6 == 0
1334
 
  if ( tt->ipv6 )
1335
 
    msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
1336
 
#endif
1337
 
 
1338
 
  /*
1339
 
   * We handle --dev null specially, we do not open /dev/null for this.
1340
 
   */
1341
 
  if (tt->type == DEV_TYPE_NULL)
1342
 
    {
1343
 
      open_null (tt);
1344
 
    }
1345
 
  else
1346
 
    {
1347
 
      /*
1348
 
       * Process --dev-node
1349
 
       */
1350
 
      const char *node = dev_node;
1351
 
      if (!node)
1352
 
        node = "/dev/net/tun";
1353
 
 
1354
 
      /*
1355
 
       * Open the interface
1356
 
       */
1357
 
      if ((tt->fd = open (node, O_RDWR)) < 0)
1358
 
        {
1359
 
          msg (M_WARN | M_ERRNO, "Note: Cannot open TUN/TAP dev %s", node);
1360
 
          return;
1361
 
        }
1362
 
 
1363
 
      /*
1364
 
       * Process --tun-ipv6
1365
 
       */
1366
 
      CLEAR (ifr);
1367
 
      if (!tt->ipv6)
1368
 
        ifr.ifr_flags = IFF_NO_PI;
1369
 
 
1370
 
#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
1371
 
      ifr.ifr_flags |= IFF_ONE_QUEUE;
1372
 
#endif
1373
 
 
1374
 
      /*
1375
 
       * Figure out if tun or tap device
1376
 
       */
1377
 
      if (tt->type == DEV_TYPE_TUN)
1378
 
        {
1379
 
          ifr.ifr_flags |= IFF_TUN;
1380
 
        }
1381
 
      else if (tt->type == DEV_TYPE_TAP)
1382
 
        {
1383
 
          ifr.ifr_flags |= IFF_TAP;
1384
 
        }
1385
 
      else
1386
 
        {
1387
 
          msg (M_FATAL, "I don't recognize device %s as a tun or tap device",
1388
 
               dev);
1389
 
        }
1390
 
 
1391
 
      /*
1392
 
       * Set an explicit name, if --dev is not tun or tap
1393
 
       */
1394
 
      if (strcmp(dev, "tun") && strcmp(dev, "tap"))
1395
 
        strncpynt (ifr.ifr_name, dev, IFNAMSIZ);
1396
 
 
1397
 
      /*
1398
 
       * Use special ioctl that configures tun/tap device with the parms
1399
 
       * we set in ifr
1400
 
       */
1401
 
      if (ioctl (tt->fd, TUNSETIFF, (void *) &ifr) < 0)
1402
 
        {
1403
 
          msg (M_WARN | M_ERRNO, "Note: Cannot ioctl TUNSETIFF %s", dev);
1404
 
          return;
1405
 
        }
1406
 
 
1407
 
      msg (M_INFO, "TUN/TAP device %s opened", ifr.ifr_name);
1408
 
 
1409
 
      /*
1410
 
       * Try making the TX send queue bigger
1411
 
       */
1412
 
#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
1413
 
      if (tt->options.txqueuelen) {
1414
 
        struct ifreq netifr;
1415
 
        int ctl_fd;
1416
 
 
1417
 
        if ((ctl_fd = socket (AF_INET, SOCK_DGRAM, 0)) >= 0)
1418
 
          {
1419
 
            CLEAR (netifr);
1420
 
            strncpynt (netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
1421
 
            netifr.ifr_qlen = tt->options.txqueuelen;
1422
 
            if (ioctl (ctl_fd, SIOCSIFTXQLEN, (void *) &netifr) >= 0)
1423
 
              msg (D_OSBUF, "TUN/TAP TX queue length set to %d", tt->options.txqueuelen);
1424
 
            else
1425
 
              msg (M_WARN | M_ERRNO, "Note: Cannot set tx queue length on %s", ifr.ifr_name);
1426
 
            close (ctl_fd);
1427
 
          }
1428
 
        else
1429
 
          {
1430
 
            msg (M_WARN | M_ERRNO, "Note: Cannot open control socket on %s", ifr.ifr_name);
1431
 
          }
1432
 
      }
1433
 
#endif
1434
 
 
1435
 
      set_nonblock (tt->fd);
1436
 
      set_cloexec (tt->fd);
1437
 
      tt->actual_name = string_alloc (ifr.ifr_name, NULL);
1438
 
    }
1439
 
  return;
1440
 
}
1441
 
 
1442
 
#else
1443
 
 
1444
 
void
1445
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1446
 
{
1447
 
  ASSERT (0);
1448
 
}
1449
 
 
1450
 
#endif
1451
 
 
1452
 
#else
1453
 
 
1454
 
void
1455
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1456
 
{
1457
 
  open_tun_generic (dev, dev_type, dev_node, false, true, tt);
1458
 
}
1459
 
 
1460
 
#endif /* HAVE_LINUX_IF_TUN_H */
1461
 
 
1462
 
#ifdef TUNSETPERSIST
1463
 
 
1464
 
/*
1465
 
 * This can be removed in future
1466
 
 * when all systems will use newer
1467
 
 * linux-headers
1468
 
 */
1469
 
#ifndef TUNSETOWNER
1470
 
#define TUNSETOWNER     _IOW('T', 204, int)
1471
 
#endif
1472
 
#ifndef TUNSETGROUP
1473
 
#define TUNSETGROUP     _IOW('T', 206, int)
1474
 
#endif
1475
 
 
1476
 
void
1477
 
tuncfg (const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
1478
 
{
1479
 
  struct tuntap *tt;
1480
 
 
1481
 
  ALLOC_OBJ (tt, struct tuntap);
1482
 
  clear_tuntap (tt);
1483
 
  tt->type = dev_type_enum (dev, dev_type);
1484
 
  tt->options = *options;
1485
 
  open_tun (dev, dev_type, dev_node, tt);
1486
 
  if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
1487
 
    msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
1488
 
  if (username != NULL)
1489
 
    {
1490
 
      struct user_state user_state;
1491
 
 
1492
 
      if (!get_user (username, &user_state))
1493
 
        msg (M_ERR, "Cannot get user entry for %s", username);
1494
 
      else
1495
 
        if (ioctl (tt->fd, TUNSETOWNER, user_state.pw->pw_uid) < 0)
1496
 
          msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
1497
 
    }
1498
 
  if (groupname != NULL)
1499
 
    {
1500
 
      struct group_state group_state;
1501
 
 
1502
 
      if (!get_group (groupname, &group_state))
1503
 
        msg (M_ERR, "Cannot get group entry for %s", groupname);
1504
 
      else
1505
 
        if (ioctl (tt->fd, TUNSETGROUP, group_state.gr->gr_gid) < 0)
1506
 
          msg (M_ERR, "Cannot ioctl TUNSETOWNER(%s) %s", groupname, dev);
1507
 
    }
1508
 
  close_tun (tt);
1509
 
  msg (M_INFO, "Persist state set to: %s", (persist_mode ? "ON" : "OFF"));
1510
 
}
1511
 
 
1512
 
#endif /* TUNSETPERSIST */
1513
 
 
1514
 
void
1515
 
close_tun (struct tuntap *tt)
1516
 
{
1517
 
  if (tt)
1518
 
    {
1519
 
        if (tt->type != DEV_TYPE_NULL && tt->did_ifconfig)
1520
 
          {
1521
 
            struct argv argv;
1522
 
            struct gc_arena gc = gc_new ();
1523
 
            argv_init (&argv);
1524
 
 
1525
 
#ifdef CONFIG_FEATURE_IPROUTE
1526
 
            if (is_tun_p2p (tt))
1527
 
              {
1528
 
                argv_printf (&argv,
1529
 
                        "%s addr del dev %s local %s peer %s",
1530
 
                        iproute_path,
1531
 
                        tt->actual_name,
1532
 
                        print_in_addr_t (tt->local, 0, &gc),
1533
 
                        print_in_addr_t (tt->remote_netmask, 0, &gc)
1534
 
                        );
1535
 
              }
1536
 
            else
1537
 
              {
1538
 
                argv_printf (&argv,
1539
 
                        "%s addr del dev %s %s/%d",
1540
 
                        iproute_path,
1541
 
                        tt->actual_name,
1542
 
                        print_in_addr_t (tt->local, 0, &gc),
1543
 
                        count_netmask_bits(print_in_addr_t (tt->remote_netmask, 0, &gc))
1544
 
                        );
1545
 
              }
1546
 
#else
1547
 
            argv_printf (&argv,
1548
 
                        "%s %s 0.0.0.0",
1549
 
                        IFCONFIG_PATH,
1550
 
                        tt->actual_name
1551
 
                        );
1552
 
#endif
1553
 
 
1554
 
            argv_msg (M_INFO, &argv);
1555
 
            openvpn_execve_check (&argv, NULL, 0, "Linux ip addr del failed");
1556
 
 
1557
 
            argv_reset (&argv);
1558
 
            gc_free (&gc);
1559
 
          }
1560
 
      close_tun_generic (tt);
1561
 
      free (tt);
1562
 
    }
1563
 
}
1564
 
 
1565
 
int
1566
 
write_tun (struct tuntap* tt, uint8_t *buf, int len)
1567
 
{
1568
 
#if LINUX_IPV6
1569
 
  if (tt->ipv6)
1570
 
    {
1571
 
      struct tun_pi pi;
1572
 
      struct iphdr *iph;
1573
 
      struct iovec vect[2];
1574
 
      int ret;
1575
 
 
1576
 
      iph = (struct iphdr *)buf;
1577
 
 
1578
 
      pi.flags = 0;
1579
 
 
1580
 
      if(iph->version == 6)
1581
 
        pi.proto = htons(ETH_P_IPV6);
1582
 
      else
1583
 
        pi.proto = htons(ETH_P_IP);
1584
 
 
1585
 
      vect[0].iov_len = sizeof(pi);
1586
 
      vect[0].iov_base = &pi;
1587
 
      vect[1].iov_len = len;
1588
 
      vect[1].iov_base = buf;
1589
 
 
1590
 
      ret = writev(tt->fd, vect, 2);
1591
 
      return(ret - sizeof(pi));
1592
 
    }
1593
 
  else
1594
 
#endif
1595
 
    return write (tt->fd, buf, len);
1596
 
}
1597
 
 
1598
 
int
1599
 
read_tun (struct tuntap* tt, uint8_t *buf, int len)
1600
 
{
1601
 
#if LINUX_IPV6
1602
 
  if (tt->ipv6)
1603
 
    {
1604
 
      struct iovec vect[2];
1605
 
      struct tun_pi pi;
1606
 
      int ret;
1607
 
 
1608
 
      vect[0].iov_len = sizeof(pi);
1609
 
      vect[0].iov_base = &pi;
1610
 
      vect[1].iov_len = len;
1611
 
      vect[1].iov_base = buf;
1612
 
 
1613
 
      ret = readv(tt->fd, vect, 2);
1614
 
      return(ret - sizeof(pi));
1615
 
    }
1616
 
  else
1617
 
#endif
1618
 
    return read (tt->fd, buf, len);
1619
 
}
1620
 
 
1621
 
#elif defined(TARGET_SOLARIS)
1622
 
 
1623
 
#ifndef TUNNEWPPA
1624
 
#error I need the symbol TUNNEWPPA from net/if_tun.h
1625
 
#endif
1626
 
 
1627
 
void
1628
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1629
 
{
1630
 
  int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1;
1631
 
  struct lifreq ifr;
1632
 
  const char *ptr;
1633
 
  const char *ip_node, *arp_node;
1634
 
  const char *dev_tuntap_type;
1635
 
  int link_type;
1636
 
  bool is_tun;
1637
 
  struct strioctl  strioc_if, strioc_ppa;
1638
 
 
1639
 
  /* improved generic TUN/TAP driver from
1640
 
   * http://www.whiteboard.ne.jp/~admin2/tuntap/
1641
 
   * has IPv6 support
1642
 
   */
1643
 
  memset(&ifr, 0x0, sizeof(ifr));
1644
 
 
1645
 
  if (tt->type == DEV_TYPE_NULL)
1646
 
    {
1647
 
      open_null (tt);
1648
 
      return;
1649
 
    }
1650
 
 
1651
 
  if (tt->type == DEV_TYPE_TUN)
1652
 
    {
1653
 
      ip_node = "/dev/udp";
1654
 
      if (!dev_node)
1655
 
        dev_node = "/dev/tun";
1656
 
      dev_tuntap_type = "tun";
1657
 
      link_type = I_PLINK;
1658
 
      is_tun = true;
1659
 
    }
1660
 
  else if (tt->type == DEV_TYPE_TAP)
1661
 
    {
1662
 
      ip_node = "/dev/udp";
1663
 
      if (!dev_node)
1664
 
        dev_node = "/dev/tap";
1665
 
      arp_node = dev_node;
1666
 
      dev_tuntap_type = "tap";
1667
 
      link_type = I_PLINK; /* was: I_LINK */
1668
 
      is_tun = false;
1669
 
    }
1670
 
  else
1671
 
    {
1672
 
      msg (M_FATAL, "I don't recognize device %s as a tun or tap device",
1673
 
           dev);
1674
 
    }
1675
 
  
1676
 
  /* get unit number */
1677
 
  if (*dev)
1678
 
    {
1679
 
      ptr = dev;
1680
 
      while (*ptr && !isdigit ((int) *ptr))
1681
 
        ptr++;
1682
 
      ppa = atoi (ptr);
1683
 
    }
1684
 
 
1685
 
  if ((tt->ip_fd = open (ip_node, O_RDWR, 0)) < 0)
1686
 
    msg (M_ERR, "Can't open %s", ip_node);
1687
 
 
1688
 
  if ((tt->fd = open (dev_node, O_RDWR, 0)) < 0)
1689
 
    msg (M_ERR, "Can't open %s", dev_node);
1690
 
 
1691
 
  /* Assign a new PPA and get its unit number. */
1692
 
  strioc_ppa.ic_cmd = TUNNEWPPA;
1693
 
  strioc_ppa.ic_timout = 0;
1694
 
  strioc_ppa.ic_len = sizeof(ppa);
1695
 
  strioc_ppa.ic_dp = (char *)&ppa;
1696
 
  if ((ppa = ioctl (tt->fd, I_STR, &strioc_ppa)) < 0)
1697
 
    msg (M_ERR, "Can't assign new interface");
1698
 
 
1699
 
  if ((if_fd = open (dev_node, O_RDWR, 0)) < 0)
1700
 
    msg (M_ERR, "Can't open %s (2)", dev_node);
1701
 
 
1702
 
  if (ioctl (if_fd, I_PUSH, "ip") < 0)
1703
 
    msg (M_ERR, "Can't push IP module");
1704
 
 
1705
 
  if (tt->type == DEV_TYPE_TUN)
1706
 
    {
1707
 
  /* Assign ppa according to the unit number returned by tun device */
1708
 
  if (ioctl (if_fd, IF_UNITSEL, (char *) &ppa) < 0)
1709
 
    msg (M_ERR, "Can't set PPA %d", ppa);
1710
 
    }
1711
 
 
1712
 
  tt->actual_name = (char *) malloc (32);
1713
 
  check_malloc_return (tt->actual_name);
1714
 
 
1715
 
  openvpn_snprintf (tt->actual_name, 32, "%s%d", dev_tuntap_type, ppa);
1716
 
 
1717
 
  if (tt->type == DEV_TYPE_TAP)
1718
 
    {
1719
 
          if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
1720
 
            msg (M_ERR, "Can't get flags\n");
1721
 
          strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
1722
 
          ifr.lifr_ppa = ppa;
1723
 
          /* Assign ppa according to the unit number returned by tun device */
1724
 
          if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
1725
 
            msg (M_ERR, "Can't set PPA %d", ppa);
1726
 
          if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
1727
 
            msg (M_ERR, "Can't get flags\n");
1728
 
          /* Push arp module to if_fd */
1729
 
          if (ioctl (if_fd, I_PUSH, "arp") < 0)
1730
 
            msg (M_ERR, "Can't push ARP module");
1731
 
 
1732
 
          /* Pop any modules on the stream */
1733
 
          while (true)
1734
 
            {
1735
 
                 if (ioctl (tt->ip_fd, I_POP, NULL) < 0)
1736
 
                     break;
1737
 
            }
1738
 
          /* Push arp module to ip_fd */
1739
 
          if (ioctl (tt->ip_fd, I_PUSH, "arp") < 0)
1740
 
            msg (M_ERR, "Can't push ARP module\n");
1741
 
 
1742
 
          /* Open arp_fd */
1743
 
          if ((arp_fd = open (arp_node, O_RDWR, 0)) < 0)
1744
 
            msg (M_ERR, "Can't open %s\n", arp_node);
1745
 
          /* Push arp module to arp_fd */
1746
 
          if (ioctl (arp_fd, I_PUSH, "arp") < 0)
1747
 
            msg (M_ERR, "Can't push ARP module\n");
1748
 
 
1749
 
          /* Set ifname to arp */
1750
 
          strioc_if.ic_cmd = SIOCSLIFNAME;
1751
 
          strioc_if.ic_timout = 0;
1752
 
          strioc_if.ic_len = sizeof(ifr);
1753
 
          strioc_if.ic_dp = (char *)&ifr;
1754
 
          if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
1755
 
              msg (M_ERR, "Can't set ifname to arp\n");
1756
 
          }
1757
 
   }
1758
 
 
1759
 
  if ((ip_muxid = ioctl (tt->ip_fd, link_type, if_fd)) < 0)
1760
 
    msg (M_ERR, "Can't link %s device to IP", dev_tuntap_type);
1761
 
 
1762
 
  if (tt->type == DEV_TYPE_TAP) {
1763
 
          if ((arp_muxid = ioctl (tt->ip_fd, link_type, arp_fd)) < 0)
1764
 
            msg (M_ERR, "Can't link %s device to ARP", dev_tuntap_type);
1765
 
          close (arp_fd);
1766
 
  }
1767
 
 
1768
 
  CLEAR (ifr);
1769
 
  strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
1770
 
  ifr.lifr_ip_muxid  = ip_muxid;
1771
 
  if (tt->type == DEV_TYPE_TAP) {
1772
 
          ifr.lifr_arp_muxid = arp_muxid;
1773
 
  }
1774
 
 
1775
 
  if (ioctl (tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
1776
 
    {
1777
 
      if (tt->type == DEV_TYPE_TAP)
1778
 
        {
1779
 
              ioctl (tt->ip_fd, I_PUNLINK , arp_muxid);
1780
 
        }
1781
 
      ioctl (tt->ip_fd, I_PUNLINK, ip_muxid);
1782
 
      msg (M_ERR, "Can't set multiplexor id");
1783
 
    }
1784
 
 
1785
 
  set_nonblock (tt->fd);
1786
 
  set_cloexec (tt->fd);
1787
 
  set_cloexec (tt->ip_fd);
1788
 
 
1789
 
  msg (M_INFO, "TUN/TAP device %s opened", tt->actual_name);
1790
 
}
1791
 
 
1792
 
static void
1793
 
solaris_close_tun (struct tuntap *tt)
1794
 
{
1795
 
  if (tt)
1796
 
    {
1797
 
      /* IPv6 interfaces need to be 'manually' de-configured */
1798
 
      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
1799
 
        {
1800
 
          struct argv argv;
1801
 
          argv_init (&argv);
1802
 
          argv_printf( &argv, "%s %s inet6 unplumb",
1803
 
                       IFCONFIG_PATH, tt->actual_name );
1804
 
          argv_msg (M_INFO, &argv);
1805
 
          openvpn_execve_check (&argv, NULL, 0, "Solaris ifconfig inet6 unplumb failed");
1806
 
          argv_reset (&argv);
1807
 
        }
1808
 
 
1809
 
      if (tt->ip_fd >= 0)
1810
 
        {
1811
 
          struct lifreq ifr;
1812
 
          CLEAR (ifr);
1813
 
          strncpynt (ifr.lifr_name, tt->actual_name, sizeof (ifr.lifr_name));
1814
 
 
1815
 
          if (ioctl (tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
1816
 
            msg (M_WARN | M_ERRNO, "Can't get iface flags");
1817
 
 
1818
 
          if (ioctl (tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
1819
 
            msg (M_WARN | M_ERRNO, "Can't get multiplexor id");
1820
 
 
1821
 
          if (tt->type == DEV_TYPE_TAP)
1822
 
            {
1823
 
                  if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
1824
 
                    msg (M_WARN | M_ERRNO, "Can't unlink interface(arp)");
1825
 
            }
1826
 
 
1827
 
          if (ioctl (tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
1828
 
            msg (M_WARN | M_ERRNO, "Can't unlink interface(ip)");
1829
 
 
1830
 
          close (tt->ip_fd);
1831
 
          tt->ip_fd = -1;
1832
 
        }
1833
 
 
1834
 
      if (tt->fd >= 0)
1835
 
        {
1836
 
          close (tt->fd);
1837
 
          tt->fd = -1;
1838
 
        }
1839
 
    }
1840
 
}
1841
 
 
1842
 
/*
1843
 
 * Close TUN device. 
1844
 
 */
1845
 
void
1846
 
close_tun (struct tuntap *tt)
1847
 
{
1848
 
  if (tt)
1849
 
    {
1850
 
      solaris_close_tun (tt);
1851
 
 
1852
 
      if (tt->actual_name)
1853
 
        free (tt->actual_name);
1854
 
      
1855
 
      clear_tuntap (tt);
1856
 
      free (tt);
1857
 
    }
1858
 
}
1859
 
 
1860
 
static void
1861
 
solaris_error_close (struct tuntap *tt, const struct env_set *es, 
1862
 
                     const char *actual, bool unplumb_inet6 )
1863
 
{
1864
 
  struct argv argv;
1865
 
  argv_init (&argv);
1866
 
 
1867
 
  if (unplumb_inet6)
1868
 
    {
1869
 
      argv_printf( &argv, "%s %s inet6 unplumb",
1870
 
                   IFCONFIG_PATH, actual );
1871
 
      argv_msg (M_INFO, &argv);
1872
 
      openvpn_execve_check (&argv, es, 0, "Solaris ifconfig inet6 unplumb failed");
1873
 
    }
1874
 
 
1875
 
  argv_printf (&argv,
1876
 
                    "%s %s unplumb",
1877
 
                    IFCONFIG_PATH,
1878
 
                    actual);
1879
 
 
1880
 
  argv_msg (M_INFO, &argv);
1881
 
  openvpn_execve_check (&argv, es, 0, "Solaris ifconfig unplumb failed");
1882
 
  close_tun (tt);
1883
 
  msg (M_FATAL, "Solaris ifconfig failed");
1884
 
  argv_reset (&argv);
1885
 
}
1886
 
 
1887
 
int
1888
 
write_tun (struct tuntap* tt, uint8_t *buf, int len)
1889
 
{
1890
 
  struct strbuf sbuf;
1891
 
  sbuf.len = len;
1892
 
  sbuf.buf = (char *)buf;
1893
 
  return putmsg (tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
1894
 
}
1895
 
 
1896
 
int
1897
 
read_tun (struct tuntap* tt, uint8_t *buf, int len)
1898
 
{
1899
 
  struct strbuf sbuf;
1900
 
  int f = 0;
1901
 
 
1902
 
  sbuf.maxlen = len;
1903
 
  sbuf.buf = (char *)buf;
1904
 
  return getmsg (tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
1905
 
}
1906
 
 
1907
 
#elif defined(TARGET_OPENBSD)
1908
 
 
1909
 
#if !defined(HAVE_READV) || !defined(HAVE_WRITEV)
1910
 
#error openbsd build requires readv & writev library functions
1911
 
#endif
1912
 
 
1913
 
/*
1914
 
 * OpenBSD has a slightly incompatible TUN device from
1915
 
 * the rest of the world, in that it prepends a
1916
 
 * uint32 to the beginning of the IP header
1917
 
 * to designate the protocol (why not just
1918
 
 * look at the version field in the IP header to
1919
 
 * determine v4 or v6?).
1920
 
 *
1921
 
 * We strip off this field on reads and
1922
 
 * put it back on writes.
1923
 
 *
1924
 
 * I have not tested TAP devices on OpenBSD,
1925
 
 * but I have conditionalized the special
1926
 
 * TUN handling code described above to
1927
 
 * go away for TAP devices.
1928
 
 */
1929
 
 
1930
 
void
1931
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1932
 
{
1933
 
  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
1934
 
 
1935
 
  /* Enable multicast on the interface */
1936
 
  if (tt->fd >= 0)
1937
 
    {
1938
 
      struct tuninfo info;
1939
 
 
1940
 
      if (ioctl (tt->fd, TUNGIFINFO, &info) < 0) {
1941
 
        msg (M_WARN | M_ERRNO, "Can't get interface info: %s",
1942
 
          strerror(errno));
1943
 
      }
1944
 
 
1945
 
#ifdef IFF_MULTICAST /* openbsd 4.x doesn't have this */
1946
 
      info.flags |= IFF_MULTICAST;
1947
 
#endif
1948
 
 
1949
 
      if (ioctl (tt->fd, TUNSIFINFO, &info) < 0) {
1950
 
        msg (M_WARN | M_ERRNO, "Can't set interface info: %s",
1951
 
          strerror(errno));
1952
 
      }
1953
 
    }
1954
 
}
1955
 
 
1956
 
/* the current way OpenVPN handles tun devices on OpenBSD leads to
1957
 
 * lingering tunX interfaces after close -> for a full cleanup, they
1958
 
 * need to be explicitely destroyed
1959
 
 */
1960
 
 
1961
 
void
1962
 
close_tun (struct tuntap* tt)
1963
 
{
1964
 
  if (tt)
1965
 
    {
1966
 
      struct gc_arena gc = gc_new ();
1967
 
      struct argv argv;
1968
 
 
1969
 
      /* setup command, close tun dev (clears tt->actual_name!), run command
1970
 
       */
1971
 
 
1972
 
      argv_init (&argv);
1973
 
      argv_printf (&argv, "%s %s destroy",
1974
 
                          IFCONFIG_PATH, tt->actual_name);
1975
 
 
1976
 
      close_tun_generic (tt);
1977
 
 
1978
 
      argv_msg (M_INFO, &argv);
1979
 
      openvpn_execve_check (&argv, NULL, 0, "OpenBSD 'destroy tun interface' failed (non-critical)");
1980
 
 
1981
 
      free (tt);
1982
 
    }
1983
 
}
1984
 
 
1985
 
static inline int
1986
 
openbsd_modify_read_write_return (int len)
1987
 
{
1988
 
 if (len > 0)
1989
 
    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
1990
 
  else
1991
 
    return len;
1992
 
}
1993
 
 
1994
 
int
1995
 
write_tun (struct tuntap* tt, uint8_t *buf, int len)
1996
 
{
1997
 
  if (tt->type == DEV_TYPE_TUN)
1998
 
    {
1999
 
      u_int32_t type;
2000
 
      struct iovec iv[2];
2001
 
      struct ip *iph;
2002
 
 
2003
 
      iph = (struct ip *) buf;
2004
 
 
2005
 
      if (tt->ipv6 && iph->ip_v == 6)
2006
 
        type = htonl (AF_INET6);
2007
 
      else 
2008
 
        type = htonl (AF_INET);
2009
 
 
2010
 
      iv[0].iov_base = &type;
2011
 
      iv[0].iov_len = sizeof (type);
2012
 
      iv[1].iov_base = buf;
2013
 
      iv[1].iov_len = len;
2014
 
 
2015
 
      return openbsd_modify_read_write_return (writev (tt->fd, iv, 2));
2016
 
    }
2017
 
  else
2018
 
    return write (tt->fd, buf, len);
2019
 
}
2020
 
 
2021
 
int
2022
 
read_tun (struct tuntap* tt, uint8_t *buf, int len)
2023
 
{
2024
 
  if (tt->type == DEV_TYPE_TUN)
2025
 
    {
2026
 
      u_int32_t type;
2027
 
      struct iovec iv[2];
2028
 
 
2029
 
      iv[0].iov_base = &type;
2030
 
      iv[0].iov_len = sizeof (type);
2031
 
      iv[1].iov_base = buf;
2032
 
      iv[1].iov_len = len;
2033
 
 
2034
 
      return openbsd_modify_read_write_return (readv (tt->fd, iv, 2));
2035
 
    }
2036
 
  else
2037
 
    return read (tt->fd, buf, len);
2038
 
}
2039
 
 
2040
 
#elif defined(TARGET_NETBSD)
2041
 
 
2042
 
/*
2043
 
 * NetBSD before 4.0 does not support IPv6 on tun out of the box,
2044
 
 * but there exists a patch (sys/net/if_tun.c, 1.79->1.80, see PR 32944).
2045
 
 *
2046
 
 * NetBSD 4.0 and up do, but we need to put the tun interface into
2047
 
 * "multi_af" mode, which will prepend the address family to all packets
2048
 
 * (same as OpenBSD and FreeBSD).  If this is not enabled, the kernel
2049
 
 * silently drops all IPv6 packets on output and gets confused on input.
2050
 
 *
2051
 
 * On earlier versions, multi_af is not available at all, so we have
2052
 
 * two different NetBSD code variants here :-(
2053
 
 *
2054
 
 */
2055
 
 
2056
 
void
2057
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2058
 
{
2059
 
#ifdef NETBSD_MULTI_AF
2060
 
    open_tun_generic (dev, dev_type, dev_node, true, true, tt);
2061
 
#else
2062
 
    open_tun_generic (dev, dev_type, dev_node, false, true, tt);
2063
 
#endif
2064
 
 
2065
 
    if (tt->fd >= 0)
2066
 
      {
2067
 
        int i = IFF_POINTOPOINT|IFF_MULTICAST;
2068
 
        ioctl (tt->fd, TUNSIFMODE, &i);  /* multicast on */
2069
 
        i = 0;
2070
 
        ioctl (tt->fd, TUNSLMODE, &i);   /* link layer mode off */
2071
 
 
2072
 
#ifdef NETBSD_MULTI_AF
2073
 
        i = 1;
2074
 
        if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0)         /* multi-af mode on */
2075
 
          {
2076
 
            msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
2077
 
          }
2078
 
#endif
2079
 
      }
2080
 
}
2081
 
 
2082
 
void
2083
 
close_tun (struct tuntap *tt)
2084
 
{
2085
 
  /* TODO: we really should cleanup non-persistant tunX with 
2086
 
   * "ifconfig tunX destroy" here...
2087
 
   */
2088
 
  if (tt)
2089
 
    {
2090
 
      close_tun_generic (tt);
2091
 
      free (tt);
2092
 
    }
2093
 
}
2094
 
 
2095
 
#ifdef NETBSD_MULTI_AF
2096
 
 
2097
 
static inline int
2098
 
netbsd_modify_read_write_return (int len)
2099
 
{
2100
 
  if (len > 0)
2101
 
    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
2102
 
  else
2103
 
    return len;
2104
 
}
2105
 
 
2106
 
int
2107
 
write_tun (struct tuntap* tt, uint8_t *buf, int len)
2108
 
{
2109
 
  if (tt->type == DEV_TYPE_TUN)
2110
 
    {
2111
 
      u_int32_t type;
2112
 
      struct iovec iv[2];
2113
 
      struct openvpn_iphdr *iph;
2114
 
 
2115
 
      iph = (struct openvpn_iphdr *) buf;
2116
 
 
2117
 
      if (tt->ipv6 && OPENVPN_IPH_GET_VER(iph->version_len) == 6)
2118
 
        type = htonl (AF_INET6);
2119
 
      else 
2120
 
        type = htonl (AF_INET);
2121
 
 
2122
 
      iv[0].iov_base = (char *)&type;
2123
 
      iv[0].iov_len = sizeof (type);
2124
 
      iv[1].iov_base = buf;
2125
 
      iv[1].iov_len = len;
2126
 
 
2127
 
      return netbsd_modify_read_write_return (writev (tt->fd, iv, 2));
2128
 
    }
2129
 
  else
2130
 
    return write (tt->fd, buf, len);
2131
 
}
2132
 
 
2133
 
int
2134
 
read_tun (struct tuntap* tt, uint8_t *buf, int len)
2135
 
{
2136
 
  if (tt->type == DEV_TYPE_TUN)
2137
 
    {
2138
 
      u_int32_t type;
2139
 
      struct iovec iv[2];
2140
 
 
2141
 
      iv[0].iov_base = (char *)&type;
2142
 
      iv[0].iov_len = sizeof (type);
2143
 
      iv[1].iov_base = buf;
2144
 
      iv[1].iov_len = len;
2145
 
 
2146
 
      return netbsd_modify_read_write_return (readv (tt->fd, iv, 2));
2147
 
    }
2148
 
  else
2149
 
    return read (tt->fd, buf, len);
2150
 
}
2151
 
 
2152
 
#else   /* not NETBSD_MULTI_AF -> older code, IPv4 only */
2153
 
 
2154
 
int
2155
 
write_tun (struct tuntap* tt, uint8_t *buf, int len)
2156
 
{
2157
 
    return write (tt->fd, buf, len);
2158
 
}
2159
 
 
2160
 
int
2161
 
read_tun (struct tuntap* tt, uint8_t *buf, int len)
2162
 
{
2163
 
    return read (tt->fd, buf, len);
2164
 
}
2165
 
#endif  /* NETBSD_MULTI_AF */
2166
 
 
2167
 
#elif defined(TARGET_FREEBSD)
2168
 
 
2169
 
static inline int
2170
 
freebsd_modify_read_write_return (int len)
2171
 
{
2172
 
  if (len > 0)
2173
 
    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
2174
 
  else
2175
 
    return len;
2176
 
}
2177
 
 
2178
 
void
2179
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2180
 
{
2181
 
  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
2182
 
 
2183
 
  if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
2184
 
    {
2185
 
      int i = 0;
2186
 
 
2187
 
      i = tt->topology == TOP_SUBNET ? IFF_BROADCAST : IFF_POINTOPOINT;
2188
 
      i |= IFF_MULTICAST;
2189
 
      if (ioctl (tt->fd, TUNSIFMODE, &i) < 0) {
2190
 
        msg (M_WARN | M_ERRNO, "ioctl(TUNSIFMODE): %s", strerror(errno));
2191
 
      }
2192
 
      i = 1;
2193
 
      if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) {
2194
 
        msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
2195
 
      }
2196
 
    }
2197
 
}
2198
 
 
2199
 
void
2200
 
close_tun (struct tuntap *tt)
2201
 
{
2202
 
  if (tt)
2203
 
    {
2204
 
      close_tun_generic (tt);
2205
 
      free (tt);
2206
 
    }
2207
 
}
2208
 
 
2209
 
int
2210
 
write_tun (struct tuntap* tt, uint8_t *buf, int len)
2211
 
{
2212
 
  if (tt->type == DEV_TYPE_TUN)
2213
 
    {
2214
 
      u_int32_t type;
2215
 
      struct iovec iv[2];
2216
 
      struct ip *iph;
2217
 
 
2218
 
      iph = (struct ip *) buf;
2219
 
 
2220
 
      if (tt->ipv6 && iph->ip_v == 6)
2221
 
        type = htonl (AF_INET6);
2222
 
      else 
2223
 
        type = htonl (AF_INET);
2224
 
 
2225
 
      iv[0].iov_base = (char *)&type;
2226
 
      iv[0].iov_len = sizeof (type);
2227
 
      iv[1].iov_base = buf;
2228
 
      iv[1].iov_len = len;
2229
 
 
2230
 
      return freebsd_modify_read_write_return (writev (tt->fd, iv, 2));
2231
 
    }
2232
 
  else
2233
 
    return write (tt->fd, buf, len);
2234
 
}
2235
 
 
2236
 
int
2237
 
read_tun (struct tuntap* tt, uint8_t *buf, int len)
2238
 
{
2239
 
  if (tt->type == DEV_TYPE_TUN)
2240
 
    {
2241
 
      u_int32_t type;
2242
 
      struct iovec iv[2];
2243
 
 
2244
 
      iv[0].iov_base = (char *)&type;
2245
 
      iv[0].iov_len = sizeof (type);
2246
 
      iv[1].iov_base = buf;
2247
 
      iv[1].iov_len = len;
2248
 
 
2249
 
      return freebsd_modify_read_write_return (readv (tt->fd, iv, 2));
2250
 
    }
2251
 
  else
2252
 
    return read (tt->fd, buf, len);
2253
 
}
2254
 
 
2255
 
#elif defined(TARGET_DRAGONFLY)
2256
 
 
2257
 
static inline int
2258
 
dragonfly_modify_read_write_return (int len)
2259
 
{
2260
 
  if (len > 0)
2261
 
    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
2262
 
  else
2263
 
    return len;
2264
 
}
2265
 
 
2266
 
void
2267
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2268
 
{
2269
 
  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
2270
 
 
2271
 
  if (tt->fd >= 0)
2272
 
    {
2273
 
      int i = 0;
2274
 
 
2275
 
      /* Disable extended modes */
2276
 
      ioctl (tt->fd, TUNSLMODE, &i);
2277
 
      i = 1;
2278
 
      ioctl (tt->fd, TUNSIFHEAD, &i);
2279
 
    }
2280
 
}
2281
 
 
2282
 
void
2283
 
close_tun (struct tuntap *tt)
2284
 
{
2285
 
  if (tt)
2286
 
    {
2287
 
      close_tun_generic (tt);
2288
 
      free (tt);
2289
 
    }
2290
 
}
2291
 
 
2292
 
int
2293
 
write_tun (struct tuntap* tt, uint8_t *buf, int len)
2294
 
{
2295
 
  if (tt->type == DEV_TYPE_TUN)
2296
 
    {
2297
 
      u_int32_t type;
2298
 
      struct iovec iv[2];
2299
 
      struct ip *iph;
2300
 
 
2301
 
      iph = (struct ip *) buf;
2302
 
 
2303
 
      if (tt->ipv6 && iph->ip_v == 6)
2304
 
        type = htonl (AF_INET6);
2305
 
      else 
2306
 
        type = htonl (AF_INET);
2307
 
 
2308
 
      iv[0].iov_base = (char *)&type;
2309
 
      iv[0].iov_len = sizeof (type);
2310
 
      iv[1].iov_base = buf;
2311
 
      iv[1].iov_len = len;
2312
 
 
2313
 
      return dragonfly_modify_read_write_return (writev (tt->fd, iv, 2));
2314
 
    }
2315
 
  else
2316
 
    return write (tt->fd, buf, len);
2317
 
}
2318
 
 
2319
 
int
2320
 
read_tun (struct tuntap* tt, uint8_t *buf, int len)
2321
 
{
2322
 
  if (tt->type == DEV_TYPE_TUN)
2323
 
    {
2324
 
      u_int32_t type;
2325
 
      struct iovec iv[2];
2326
 
 
2327
 
      iv[0].iov_base = (char *)&type;
2328
 
      iv[0].iov_len = sizeof (type);
2329
 
      iv[1].iov_base = buf;
2330
 
      iv[1].iov_len = len;
2331
 
 
2332
 
      return dragonfly_modify_read_write_return (readv (tt->fd, iv, 2));
2333
 
    }
2334
 
  else
2335
 
    return read (tt->fd, buf, len);
2336
 
}
2337
 
 
2338
 
#elif defined(TARGET_DARWIN)
2339
 
 
2340
 
/* Darwin (MacOS X) is mostly "just use the generic stuff", but there
2341
 
 * is always one caveat...:
2342
 
 *
2343
 
 * If IPv6 is configured, and the tun device is closed, the IPv6 address
2344
 
 * configured to the tun interface changes to a lingering /128 route
2345
 
 * pointing to lo0.  Need to unconfigure...  (observed on 10.5)
2346
 
 */
2347
 
 
2348
 
void
2349
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2350
 
{
2351
 
  open_tun_generic (dev, dev_type, dev_node, false, true, tt);
2352
 
}
2353
 
 
2354
 
void
2355
 
close_tun (struct tuntap* tt)
2356
 
{
2357
 
  if (tt)
2358
 
    {
2359
 
      struct gc_arena gc = gc_new ();
2360
 
      struct argv argv;
2361
 
      argv_init (&argv);
2362
 
 
2363
 
      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
2364
 
        {
2365
 
          const char * ifconfig_ipv6_local =
2366
 
                                print_in6_addr (tt->local_ipv6, 0, &gc);
2367
 
 
2368
 
          argv_printf (&argv, "%s delete -inet6 %s",
2369
 
                              ROUTE_PATH, ifconfig_ipv6_local );
2370
 
          argv_msg (M_INFO, &argv);
2371
 
          openvpn_execve_check (&argv, NULL, 0, "MacOS X 'remove inet6 route' failed (non-critical)");
2372
 
        }
2373
 
 
2374
 
      close_tun_generic (tt);
2375
 
      free (tt);
2376
 
      argv_reset (&argv);
2377
 
      gc_free (&gc);
2378
 
    }
2379
 
}
2380
 
 
2381
 
int
2382
 
write_tun (struct tuntap* tt, uint8_t *buf, int len)
2383
 
{
2384
 
  return write (tt->fd, buf, len);
2385
 
}
2386
 
 
2387
 
int
2388
 
read_tun (struct tuntap* tt, uint8_t *buf, int len)
2389
 
{
2390
 
  return read (tt->fd, buf, len);
2391
 
}
2392
 
 
2393
 
#elif defined(WIN32)
2394
 
 
2395
 
int
2396
 
tun_read_queue (struct tuntap *tt, int maxsize)
2397
 
{
2398
 
  if (tt->reads.iostate == IOSTATE_INITIAL)
2399
 
    {
2400
 
      DWORD len;
2401
 
      BOOL status;
2402
 
      int err;
2403
 
 
2404
 
      /* reset buf to its initial state */
2405
 
      tt->reads.buf = tt->reads.buf_init;
2406
 
 
2407
 
      len = maxsize ? maxsize : BLEN (&tt->reads.buf);
2408
 
      ASSERT (len <= BLEN (&tt->reads.buf));
2409
 
 
2410
 
      /* the overlapped read will signal this event on I/O completion */
2411
 
      ASSERT (ResetEvent (tt->reads.overlapped.hEvent));
2412
 
 
2413
 
      status = ReadFile(
2414
 
                      tt->hand,
2415
 
                      BPTR (&tt->reads.buf),
2416
 
                      len,
2417
 
                      &tt->reads.size,
2418
 
                      &tt->reads.overlapped
2419
 
                      );
2420
 
 
2421
 
      if (status) /* operation completed immediately? */
2422
 
        {
2423
 
          /* since we got an immediate return, we must signal the event object ourselves */
2424
 
          ASSERT (SetEvent (tt->reads.overlapped.hEvent));
2425
 
 
2426
 
          tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
2427
 
          tt->reads.status = 0;
2428
 
 
2429
 
          dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read immediate return [%d,%d]",
2430
 
               (int) len,
2431
 
               (int) tt->reads.size);          
2432
 
        }
2433
 
      else
2434
 
        {
2435
 
          err = GetLastError (); 
2436
 
          if (err == ERROR_IO_PENDING) /* operation queued? */
2437
 
            {
2438
 
              tt->reads.iostate = IOSTATE_QUEUED;
2439
 
              tt->reads.status = err;
2440
 
              dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read queued [%d]",
2441
 
                   (int) len);
2442
 
            }
2443
 
          else /* error occurred */
2444
 
            {
2445
 
              struct gc_arena gc = gc_new ();
2446
 
              ASSERT (SetEvent (tt->reads.overlapped.hEvent));
2447
 
              tt->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
2448
 
              tt->reads.status = err;
2449
 
              dmsg (D_WIN32_IO, "WIN32 I/O: TAP Read error [%d] : %s",
2450
 
                   (int) len,
2451
 
                   strerror_win32 (status, &gc));
2452
 
              gc_free (&gc);
2453
 
            }
2454
 
        }
2455
 
    }
2456
 
  return tt->reads.iostate;
2457
 
}
2458
 
 
2459
 
int
2460
 
tun_write_queue (struct tuntap *tt, struct buffer *buf)
2461
 
{
2462
 
  if (tt->writes.iostate == IOSTATE_INITIAL)
2463
 
    {
2464
 
      BOOL status;
2465
 
      int err;
2466
 
 
2467
 
      /* make a private copy of buf */
2468
 
      tt->writes.buf = tt->writes.buf_init;
2469
 
      tt->writes.buf.len = 0;
2470
 
      ASSERT (buf_copy (&tt->writes.buf, buf));
2471
 
 
2472
 
      /* the overlapped write will signal this event on I/O completion */
2473
 
      ASSERT (ResetEvent (tt->writes.overlapped.hEvent));
2474
 
 
2475
 
      status = WriteFile(
2476
 
                        tt->hand,
2477
 
                        BPTR (&tt->writes.buf),
2478
 
                        BLEN (&tt->writes.buf),
2479
 
                        &tt->writes.size,
2480
 
                        &tt->writes.overlapped
2481
 
                        );
2482
 
 
2483
 
      if (status) /* operation completed immediately? */
2484
 
        {
2485
 
          tt->writes.iostate = IOSTATE_IMMEDIATE_RETURN;
2486
 
 
2487
 
          /* since we got an immediate return, we must signal the event object ourselves */
2488
 
          ASSERT (SetEvent (tt->writes.overlapped.hEvent));
2489
 
 
2490
 
          tt->writes.status = 0;
2491
 
 
2492
 
          dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write immediate return [%d,%d]",
2493
 
               BLEN (&tt->writes.buf),
2494
 
               (int) tt->writes.size);         
2495
 
        }
2496
 
      else
2497
 
        {
2498
 
          err = GetLastError (); 
2499
 
          if (err == ERROR_IO_PENDING) /* operation queued? */
2500
 
            {
2501
 
              tt->writes.iostate = IOSTATE_QUEUED;
2502
 
              tt->writes.status = err;
2503
 
              dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write queued [%d]",
2504
 
                   BLEN (&tt->writes.buf));
2505
 
            }
2506
 
          else /* error occurred */
2507
 
            {
2508
 
              struct gc_arena gc = gc_new ();
2509
 
              ASSERT (SetEvent (tt->writes.overlapped.hEvent));
2510
 
              tt->writes.iostate = IOSTATE_IMMEDIATE_RETURN;
2511
 
              tt->writes.status = err;
2512
 
              dmsg (D_WIN32_IO, "WIN32 I/O: TAP Write error [%d] : %s",
2513
 
                   BLEN (&tt->writes.buf),
2514
 
                   strerror_win32 (err, &gc));
2515
 
              gc_free (&gc);
2516
 
            }
2517
 
        }
2518
 
    }
2519
 
  return tt->writes.iostate;
2520
 
}
2521
 
 
2522
 
int
2523
 
tun_finalize (
2524
 
              HANDLE h,
2525
 
              struct overlapped_io *io,
2526
 
              struct buffer *buf)
2527
 
{
2528
 
  int ret = -1;
2529
 
  BOOL status;
2530
 
 
2531
 
  switch (io->iostate)
2532
 
    {
2533
 
    case IOSTATE_QUEUED:
2534
 
      status = GetOverlappedResult(
2535
 
                                   h,
2536
 
                                   &io->overlapped,
2537
 
                                   &io->size,
2538
 
                                   FALSE
2539
 
                                   );
2540
 
      if (status)
2541
 
        {
2542
 
          /* successful return for a queued operation */
2543
 
          if (buf)
2544
 
            *buf = io->buf;
2545
 
          ret = io->size;
2546
 
          io->iostate = IOSTATE_INITIAL;
2547
 
          ASSERT (ResetEvent (io->overlapped.hEvent));
2548
 
          dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion success [%d]", ret);
2549
 
        }
2550
 
      else
2551
 
        {
2552
 
          /* error during a queued operation */
2553
 
          ret = -1;
2554
 
          if (GetLastError() != ERROR_IO_INCOMPLETE)
2555
 
            {
2556
 
              /* if no error (i.e. just not finished yet),
2557
 
                 then DON'T execute this code */
2558
 
              io->iostate = IOSTATE_INITIAL;
2559
 
              ASSERT (ResetEvent (io->overlapped.hEvent));
2560
 
              msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion error");
2561
 
            }
2562
 
        }
2563
 
      break;
2564
 
 
2565
 
    case IOSTATE_IMMEDIATE_RETURN:
2566
 
      io->iostate = IOSTATE_INITIAL;
2567
 
      ASSERT (ResetEvent (io->overlapped.hEvent));
2568
 
      if (io->status)
2569
 
        {
2570
 
          /* error return for a non-queued operation */
2571
 
          SetLastError (io->status);
2572
 
          ret = -1;
2573
 
          msg (D_WIN32_IO | M_ERRNO, "WIN32 I/O: TAP Completion non-queued error");
2574
 
        }
2575
 
      else
2576
 
        {
2577
 
          /* successful return for a non-queued operation */
2578
 
          if (buf)
2579
 
            *buf = io->buf;
2580
 
          ret = io->size;
2581
 
          dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion non-queued success [%d]", ret);
2582
 
        }
2583
 
      break;
2584
 
 
2585
 
    case IOSTATE_INITIAL: /* were we called without proper queueing? */
2586
 
      SetLastError (ERROR_INVALID_FUNCTION);
2587
 
      ret = -1;
2588
 
      dmsg (D_WIN32_IO, "WIN32 I/O: TAP Completion BAD STATE");
2589
 
      break;
2590
 
 
2591
 
    default:
2592
 
      ASSERT (0);
2593
 
    }
2594
 
 
2595
 
  if (buf)
2596
 
    buf->len = ret;
2597
 
  return ret;
2598
 
}
2599
 
 
2600
 
const struct tap_reg *
2601
 
get_tap_reg (struct gc_arena *gc)
2602
 
{
2603
 
  HKEY adapter_key;
2604
 
  LONG status;
2605
 
  DWORD len;
2606
 
  struct tap_reg *first = NULL;
2607
 
  struct tap_reg *last = NULL;
2608
 
  int i = 0;
2609
 
 
2610
 
  status = RegOpenKeyEx(
2611
 
                        HKEY_LOCAL_MACHINE,
2612
 
                        ADAPTER_KEY,
2613
 
                        0,
2614
 
                        KEY_READ,
2615
 
                        &adapter_key);
2616
 
 
2617
 
  if (status != ERROR_SUCCESS)
2618
 
    msg (M_FATAL, "Error opening registry key: %s", ADAPTER_KEY);
2619
 
 
2620
 
  while (true)
2621
 
    {
2622
 
      char enum_name[256];
2623
 
      char unit_string[256];
2624
 
      HKEY unit_key;
2625
 
      char component_id_string[] = "ComponentId";
2626
 
      char component_id[256];
2627
 
      char net_cfg_instance_id_string[] = "NetCfgInstanceId";
2628
 
      char net_cfg_instance_id[256];
2629
 
      DWORD data_type;
2630
 
 
2631
 
      len = sizeof (enum_name);
2632
 
      status = RegEnumKeyEx(
2633
 
                            adapter_key,
2634
 
                            i,
2635
 
                            enum_name,
2636
 
                            &len,
2637
 
                            NULL,
2638
 
                            NULL,
2639
 
                            NULL,
2640
 
                            NULL);
2641
 
      if (status == ERROR_NO_MORE_ITEMS)
2642
 
        break;
2643
 
      else if (status != ERROR_SUCCESS)
2644
 
        msg (M_FATAL, "Error enumerating registry subkeys of key: %s",
2645
 
             ADAPTER_KEY);
2646
 
 
2647
 
      openvpn_snprintf (unit_string, sizeof(unit_string), "%s\\%s",
2648
 
                        ADAPTER_KEY, enum_name);
2649
 
 
2650
 
      status = RegOpenKeyEx(
2651
 
                            HKEY_LOCAL_MACHINE,
2652
 
                            unit_string,
2653
 
                            0,
2654
 
                            KEY_READ,
2655
 
                            &unit_key);
2656
 
 
2657
 
      if (status != ERROR_SUCCESS)
2658
 
        dmsg (D_REGISTRY, "Error opening registry key: %s", unit_string);
2659
 
      else
2660
 
        {
2661
 
          len = sizeof (component_id);
2662
 
          status = RegQueryValueEx(
2663
 
                                   unit_key,
2664
 
                                   component_id_string,
2665
 
                                   NULL,
2666
 
                                   &data_type,
2667
 
                                   component_id,
2668
 
                                   &len);
2669
 
 
2670
 
          if (status != ERROR_SUCCESS || data_type != REG_SZ)
2671
 
            dmsg (D_REGISTRY, "Error opening registry key: %s\\%s",
2672
 
                 unit_string, component_id_string);
2673
 
          else
2674
 
            {         
2675
 
              len = sizeof (net_cfg_instance_id);
2676
 
              status = RegQueryValueEx(
2677
 
                                       unit_key,
2678
 
                                       net_cfg_instance_id_string,
2679
 
                                       NULL,
2680
 
                                       &data_type,
2681
 
                                       net_cfg_instance_id,
2682
 
                                       &len);
2683
 
 
2684
 
              if (status == ERROR_SUCCESS && data_type == REG_SZ)
2685
 
                {
2686
 
                  if (!strcmp (component_id, TAP_COMPONENT_ID))
2687
 
                    {
2688
 
                      struct tap_reg *reg;
2689
 
                      ALLOC_OBJ_CLEAR_GC (reg, struct tap_reg, gc);
2690
 
                      reg->guid = string_alloc (net_cfg_instance_id, gc);
2691
 
                      
2692
 
                      /* link into return list */
2693
 
                      if (!first)
2694
 
                        first = reg;
2695
 
                      if (last)
2696
 
                        last->next = reg;
2697
 
                      last = reg;
2698
 
                    }
2699
 
                }
2700
 
            }
2701
 
          RegCloseKey (unit_key);
2702
 
        }
2703
 
      ++i;
2704
 
    }
2705
 
 
2706
 
  RegCloseKey (adapter_key);
2707
 
  return first;
2708
 
}
2709
 
 
2710
 
const struct panel_reg *
2711
 
get_panel_reg (struct gc_arena *gc)
2712
 
{
2713
 
  LONG status;
2714
 
  HKEY network_connections_key;
2715
 
  DWORD len;
2716
 
  struct panel_reg *first = NULL;
2717
 
  struct panel_reg *last = NULL;
2718
 
  int i = 0;
2719
 
 
2720
 
  status = RegOpenKeyEx(
2721
 
                        HKEY_LOCAL_MACHINE,
2722
 
                        NETWORK_CONNECTIONS_KEY,
2723
 
                        0,
2724
 
                        KEY_READ,
2725
 
                        &network_connections_key);
2726
 
 
2727
 
  if (status != ERROR_SUCCESS)
2728
 
    msg (M_FATAL, "Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
2729
 
 
2730
 
  while (true)
2731
 
    {
2732
 
      char enum_name[256];
2733
 
      char connection_string[256];
2734
 
      HKEY connection_key;
2735
 
      char name_data[256];
2736
 
      DWORD name_type;
2737
 
      const char name_string[] = "Name";
2738
 
 
2739
 
      len = sizeof (enum_name);
2740
 
      status = RegEnumKeyEx(
2741
 
                            network_connections_key,
2742
 
                            i,
2743
 
                            enum_name,
2744
 
                            &len,
2745
 
                            NULL,
2746
 
                            NULL,
2747
 
                            NULL,
2748
 
                            NULL);
2749
 
      if (status == ERROR_NO_MORE_ITEMS)
2750
 
        break;
2751
 
      else if (status != ERROR_SUCCESS)
2752
 
        msg (M_FATAL, "Error enumerating registry subkeys of key: %s",
2753
 
             NETWORK_CONNECTIONS_KEY);
2754
 
 
2755
 
      openvpn_snprintf (connection_string, sizeof(connection_string),
2756
 
                        "%s\\%s\\Connection",
2757
 
                        NETWORK_CONNECTIONS_KEY, enum_name);
2758
 
 
2759
 
      status = RegOpenKeyEx(
2760
 
                            HKEY_LOCAL_MACHINE,
2761
 
                            connection_string,
2762
 
                            0,
2763
 
                            KEY_READ,
2764
 
                            &connection_key);
2765
 
 
2766
 
      if (status != ERROR_SUCCESS)
2767
 
        dmsg (D_REGISTRY, "Error opening registry key: %s", connection_string);
2768
 
      else
2769
 
        {
2770
 
          len = sizeof (name_data);
2771
 
          status = RegQueryValueEx(
2772
 
                                   connection_key,
2773
 
                                   name_string,
2774
 
                                   NULL,
2775
 
                                   &name_type,
2776
 
                                   name_data,
2777
 
                                   &len);
2778
 
 
2779
 
          if (status != ERROR_SUCCESS || name_type != REG_SZ)
2780
 
            dmsg (D_REGISTRY, "Error opening registry key: %s\\%s\\%s",
2781
 
                 NETWORK_CONNECTIONS_KEY, connection_string, name_string);
2782
 
          else
2783
 
            {
2784
 
              struct panel_reg *reg;
2785
 
 
2786
 
              ALLOC_OBJ_CLEAR_GC (reg, struct panel_reg, gc);
2787
 
              reg->name = string_alloc (name_data, gc);
2788
 
              reg->guid = string_alloc (enum_name, gc);
2789
 
                      
2790
 
              /* link into return list */
2791
 
              if (!first)
2792
 
                first = reg;
2793
 
              if (last)
2794
 
                last->next = reg;
2795
 
              last = reg;
2796
 
            }
2797
 
          RegCloseKey (connection_key);
2798
 
        }
2799
 
      ++i;
2800
 
    }
2801
 
 
2802
 
  RegCloseKey (network_connections_key);
2803
 
 
2804
 
  return first;
2805
 
}
2806
 
 
2807
 
/*
2808
 
 * Check that two addresses are part of the same 255.255.255.252 subnet.
2809
 
 */
2810
 
void
2811
 
verify_255_255_255_252 (in_addr_t local, in_addr_t remote)
2812
 
{
2813
 
  struct gc_arena gc = gc_new ();
2814
 
  const unsigned int mask = 3;
2815
 
  const char *err = NULL;
2816
 
 
2817
 
  if (local == remote)
2818
 
    {
2819
 
      err = "must be different";
2820
 
      goto error;
2821
 
    }
2822
 
  if ((local & (~mask)) != (remote & (~mask)))
2823
 
    {
2824
 
      err = "must exist within the same 255.255.255.252 subnet.  This is a limitation of --dev tun when used with the TAP-WIN32 driver";
2825
 
      goto error;
2826
 
    }
2827
 
  if ((local & mask) == 0
2828
 
      || (local & mask) == 3
2829
 
      || (remote & mask) == 0
2830
 
      || (remote & mask) == 3)
2831
 
    {
2832
 
      err = "cannot use the first or last address within a given 255.255.255.252 subnet.  This is a limitation of --dev tun when used with the TAP-WIN32 driver";
2833
 
      goto error;
2834
 
    }
2835
 
 
2836
 
  gc_free (&gc);
2837
 
  return;
2838
 
 
2839
 
 error:
2840
 
  msg (M_FATAL, "There is a problem in your selection of --ifconfig endpoints [local=%s, remote=%s].  The local and remote VPN endpoints %s.  Try '" PACKAGE " --show-valid-subnets' option for more info.",
2841
 
       print_in_addr_t (local, 0, &gc),
2842
 
       print_in_addr_t (remote, 0, &gc),
2843
 
       err);
2844
 
  gc_free (&gc);
2845
 
}
2846
 
 
2847
 
void show_valid_win32_tun_subnets (void)
2848
 
{
2849
 
  int i;
2850
 
  int col = 0;
2851
 
 
2852
 
  printf ("On Windows, point-to-point IP support (i.e. --dev tun)\n");
2853
 
  printf ("is emulated by the TAP-Win32 driver.  The major limitation\n");
2854
 
  printf ("imposed by this approach is that the --ifconfig local and\n");
2855
 
  printf ("remote endpoints must be part of the same 255.255.255.252\n");
2856
 
  printf ("subnet.  The following list shows examples of endpoint\n");
2857
 
  printf ("pairs which satisfy this requirement.  Only the final\n");
2858
 
  printf ("component of the IP address pairs is at issue.\n\n");
2859
 
  printf ("As an example, the following option would be correct:\n");
2860
 
  printf ("    --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
2861
 
  printf ("    --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
2862
 
  printf ("because [5,6] is part of the below list.\n\n");
2863
 
 
2864
 
  for (i = 0; i < 256; i += 4)
2865
 
    {
2866
 
      printf("[%3d,%3d] ", i+1, i+2);
2867
 
      if (++col > 4)
2868
 
        {
2869
 
          col = 0;
2870
 
          printf ("\n");
2871
 
        }
2872
 
    }
2873
 
  if (col)
2874
 
    printf ("\n");
2875
 
}
2876
 
 
2877
 
void
2878
 
show_tap_win32_adapters (int msglev, int warnlev)
2879
 
{
2880
 
  struct gc_arena gc = gc_new ();
2881
 
 
2882
 
  bool warn_panel_null = false;
2883
 
  bool warn_panel_dup = false;
2884
 
  bool warn_tap_dup = false;
2885
 
 
2886
 
  int links;
2887
 
 
2888
 
  const struct tap_reg *tr;
2889
 
  const struct tap_reg *tr1;
2890
 
  const struct panel_reg *pr;
2891
 
 
2892
 
  const struct tap_reg *tap_reg = get_tap_reg (&gc);
2893
 
  const struct panel_reg *panel_reg = get_panel_reg (&gc);
2894
 
 
2895
 
  msg (msglev, "Available TAP-WIN32 adapters [name, GUID]:");
2896
 
 
2897
 
  /* loop through each TAP-Win32 adapter registry entry */
2898
 
  for (tr = tap_reg; tr != NULL; tr = tr->next)
2899
 
    {
2900
 
      links = 0;
2901
 
 
2902
 
      /* loop through each network connections entry in the control panel */
2903
 
      for (pr = panel_reg; pr != NULL; pr = pr->next)
2904
 
        {
2905
 
          if (!strcmp (tr->guid, pr->guid))
2906
 
            {
2907
 
              msg (msglev, "'%s' %s", pr->name, tr->guid);
2908
 
              ++links;
2909
 
            }
2910
 
        }
2911
 
 
2912
 
      if (links > 1)
2913
 
        {
2914
 
          warn_panel_dup = true;
2915
 
        }
2916
 
      else if (links == 0)
2917
 
        {
2918
 
          /* a TAP adapter exists without a link from the network
2919
 
             connections control panel */
2920
 
          warn_panel_null = true;
2921
 
          msg (msglev, "[NULL] %s", tr->guid);
2922
 
        }
2923
 
    }
2924
 
 
2925
 
  /* check for TAP-Win32 adapter duplicated GUIDs */
2926
 
  for (tr = tap_reg; tr != NULL; tr = tr->next)
2927
 
    {
2928
 
      for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next)
2929
 
        {
2930
 
          if (tr != tr1 && !strcmp (tr->guid, tr1->guid))
2931
 
            warn_tap_dup = true;
2932
 
        }
2933
 
    }
2934
 
 
2935
 
  /* warn on registry inconsistencies */
2936
 
  if (warn_tap_dup)
2937
 
    msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate GUIDs");
2938
 
 
2939
 
  if (warn_panel_dup)
2940
 
    msg (warnlev, "WARNING: Some TAP-Win32 adapters have duplicate links from the Network Connections control panel");
2941
 
 
2942
 
  if (warn_panel_null)
2943
 
    msg (warnlev, "WARNING: Some TAP-Win32 adapters have no link from the Network Connections control panel");
2944
 
 
2945
 
  gc_free (&gc);
2946
 
}
2947
 
 
2948
 
/*
2949
 
 * Confirm that GUID is a TAP-Win32 adapter.
2950
 
 */
2951
 
static bool
2952
 
is_tap_win32 (const char *guid, const struct tap_reg *tap_reg)
2953
 
{
2954
 
  const struct tap_reg *tr;
2955
 
 
2956
 
  for (tr = tap_reg; tr != NULL; tr = tr->next)
2957
 
    {
2958
 
      if (guid && !strcmp (tr->guid, guid))
2959
 
        return true;
2960
 
    }
2961
 
 
2962
 
  return false;
2963
 
}
2964
 
 
2965
 
static const char *
2966
 
guid_to_name (const char *guid, const struct panel_reg *panel_reg)
2967
 
{
2968
 
  const struct panel_reg *pr;
2969
 
 
2970
 
  for (pr = panel_reg; pr != NULL; pr = pr->next)
2971
 
    {
2972
 
      if (guid && !strcmp (pr->guid, guid))
2973
 
        return pr->name;
2974
 
    }
2975
 
 
2976
 
  return NULL;
2977
 
}
2978
 
 
2979
 
static const char *
2980
 
name_to_guid (const char *name, const struct tap_reg *tap_reg, const struct panel_reg *panel_reg)
2981
 
{
2982
 
  const struct panel_reg *pr;
2983
 
 
2984
 
  for (pr = panel_reg; pr != NULL; pr = pr->next)
2985
 
    {
2986
 
      if (name && !strcmp (pr->name, name) && is_tap_win32 (pr->guid, tap_reg))
2987
 
        return pr->guid;
2988
 
    }
2989
 
 
2990
 
  return NULL;
2991
 
}
2992
 
 
2993
 
static void
2994
 
at_least_one_tap_win32 (const struct tap_reg *tap_reg)
2995
 
{
2996
 
  if (!tap_reg)
2997
 
    msg (M_FATAL, "There are no TAP-Win32 adapters on this system.  You should be able to create a TAP-Win32 adapter by going to Start -> All Programs -> " PACKAGE_NAME " -> Add a new TAP-Win32 virtual ethernet adapter.");
2998
 
}
2999
 
 
3000
 
/*
3001
 
 * Get an adapter GUID and optional actual_name from the 
3002
 
 * registry for the TAP device # = device_number.
3003
 
 */
3004
 
static const char *
3005
 
get_unspecified_device_guid (const int device_number,
3006
 
                             char *actual_name,
3007
 
                             int actual_name_size,
3008
 
                             const struct tap_reg *tap_reg_src,
3009
 
                             const struct panel_reg *panel_reg_src,
3010
 
                             struct gc_arena *gc)
3011
 
{
3012
 
  const struct tap_reg *tap_reg = tap_reg_src;
3013
 
  struct buffer ret = clear_buf ();
3014
 
  struct buffer actual = clear_buf ();
3015
 
  int i;
3016
 
 
3017
 
  ASSERT (device_number >= 0);
3018
 
 
3019
 
  /* Make sure we have at least one TAP adapter */
3020
 
  if (!tap_reg)
3021
 
    return NULL;
3022
 
 
3023
 
  /* The actual_name output buffer may be NULL */
3024
 
  if (actual_name)
3025
 
    {
3026
 
      ASSERT (actual_name_size > 0);
3027
 
      buf_set_write (&actual, actual_name, actual_name_size);
3028
 
    }
3029
 
 
3030
 
  /* Move on to specified device number */
3031
 
  for (i = 0; i < device_number; i++)
3032
 
    {
3033
 
      tap_reg = tap_reg->next;
3034
 
      if (!tap_reg)
3035
 
        return NULL;
3036
 
    }
3037
 
 
3038
 
  /* Save Network Panel name (if exists) in actual_name */
3039
 
  if (actual_name)
3040
 
    {
3041
 
      const char *act = guid_to_name (tap_reg->guid, panel_reg_src);
3042
 
      if (act)
3043
 
        buf_printf (&actual, "%s", act);
3044
 
      else
3045
 
        buf_printf (&actual, "%s", tap_reg->guid);
3046
 
    }
3047
 
 
3048
 
  /* Save GUID for return value */
3049
 
  ret = alloc_buf_gc (256, gc);
3050
 
  buf_printf (&ret, "%s", tap_reg->guid);
3051
 
  return BSTR (&ret);
3052
 
}
3053
 
 
3054
 
/*
3055
 
 * Lookup a --dev-node adapter name in the registry
3056
 
 * returning the GUID and optional actual_name.
3057
 
 */
3058
 
static const char *
3059
 
get_device_guid (const char *name,
3060
 
                 char *actual_name,
3061
 
                 int actual_name_size,
3062
 
                 const struct tap_reg *tap_reg,
3063
 
                 const struct panel_reg *panel_reg,
3064
 
                 struct gc_arena *gc)
3065
 
{
3066
 
  struct buffer ret = alloc_buf_gc (256, gc);
3067
 
  struct buffer actual = clear_buf ();
3068
 
 
3069
 
  /* Make sure we have at least one TAP adapter */
3070
 
  if (!tap_reg)
3071
 
    return NULL;
3072
 
 
3073
 
  /* The actual_name output buffer may be NULL */
3074
 
  if (actual_name)
3075
 
    {
3076
 
      ASSERT (actual_name_size > 0);
3077
 
      buf_set_write (&actual, actual_name, actual_name_size);
3078
 
    }
3079
 
 
3080
 
  /* Check if GUID was explicitly specified as --dev-node parameter */
3081
 
  if (is_tap_win32 (name, tap_reg))
3082
 
    {
3083
 
      const char *act = guid_to_name (name, panel_reg);
3084
 
      buf_printf (&ret, "%s", name);
3085
 
      if (act)
3086
 
        buf_printf (&actual, "%s", act);
3087
 
      else
3088
 
        buf_printf (&actual, "%s", name);
3089
 
      return BSTR (&ret);
3090
 
    }
3091
 
 
3092
 
  /* Lookup TAP adapter in network connections list */
3093
 
  {
3094
 
    const char *guid = name_to_guid (name, tap_reg, panel_reg);
3095
 
    if (guid)
3096
 
      {
3097
 
        buf_printf (&actual, "%s", name);
3098
 
        buf_printf (&ret, "%s", guid);
3099
 
        return BSTR (&ret);
3100
 
      }
3101
 
  }
3102
 
 
3103
 
  return NULL;
3104
 
}
3105
 
 
3106
 
/*
3107
 
 * Get adapter info list
3108
 
 */
3109
 
const IP_ADAPTER_INFO *
3110
 
get_adapter_info_list (struct gc_arena *gc)
3111
 
{
3112
 
  ULONG size = 0;
3113
 
  IP_ADAPTER_INFO *pi = NULL;
3114
 
  DWORD status;
3115
 
 
3116
 
  if ((status = GetAdaptersInfo (NULL, &size)) != ERROR_BUFFER_OVERFLOW)
3117
 
    {
3118
 
      msg (M_INFO, "GetAdaptersInfo #1 failed (status=%u) : %s",
3119
 
           (unsigned int)status,
3120
 
           strerror_win32 (status, gc));
3121
 
    }
3122
 
  else
3123
 
    {
3124
 
      pi = (PIP_ADAPTER_INFO) gc_malloc (size, false, gc);
3125
 
      if ((status = GetAdaptersInfo (pi, &size)) == NO_ERROR)
3126
 
        return pi;
3127
 
      else
3128
 
        {
3129
 
          msg (M_INFO, "GetAdaptersInfo #2 failed (status=%u) : %s",
3130
 
               (unsigned int)status,
3131
 
               strerror_win32 (status, gc));
3132
 
        }
3133
 
    }
3134
 
  return pi;
3135
 
}
3136
 
 
3137
 
const IP_PER_ADAPTER_INFO *
3138
 
get_per_adapter_info (const DWORD index, struct gc_arena *gc)
3139
 
{
3140
 
  ULONG size = 0;
3141
 
  IP_PER_ADAPTER_INFO *pi = NULL;
3142
 
  DWORD status;
3143
 
 
3144
 
  if (index != ~0)
3145
 
    {
3146
 
      if ((status = GetPerAdapterInfo (index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
3147
 
        {
3148
 
          msg (M_INFO, "GetPerAdapterInfo #1 failed (status=%u) : %s",
3149
 
               (unsigned int)status,
3150
 
               strerror_win32 (status, gc));
3151
 
        }
3152
 
      else
3153
 
        {
3154
 
          pi = (PIP_PER_ADAPTER_INFO) gc_malloc (size, false, gc);
3155
 
          if ((status = GetPerAdapterInfo ((ULONG)index, pi, &size)) == ERROR_SUCCESS)
3156
 
            return pi;
3157
 
          else
3158
 
            {
3159
 
              msg (M_INFO, "GetPerAdapterInfo #2 failed (status=%u) : %s",
3160
 
                   (unsigned int)status,
3161
 
                   strerror_win32 (status, gc));
3162
 
            }
3163
 
        }
3164
 
    }
3165
 
  return pi;
3166
 
}
3167
 
 
3168
 
static const IP_INTERFACE_INFO *
3169
 
get_interface_info_list (struct gc_arena *gc)
3170
 
{
3171
 
  ULONG size = 0;
3172
 
  IP_INTERFACE_INFO *ii = NULL;
3173
 
  DWORD status;
3174
 
 
3175
 
  if ((status = GetInterfaceInfo (NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
3176
 
    {
3177
 
      msg (M_INFO, "GetInterfaceInfo #1 failed (status=%u) : %s",
3178
 
           (unsigned int)status,
3179
 
           strerror_win32 (status, gc));
3180
 
    }
3181
 
  else
3182
 
    {
3183
 
      ii = (PIP_INTERFACE_INFO) gc_malloc (size, false, gc);
3184
 
      if ((status = GetInterfaceInfo (ii, &size)) == NO_ERROR)
3185
 
        return ii;
3186
 
      else
3187
 
        {
3188
 
          msg (M_INFO, "GetInterfaceInfo #2 failed (status=%u) : %s",
3189
 
               (unsigned int)status,
3190
 
               strerror_win32 (status, gc));
3191
 
        }
3192
 
    }
3193
 
  return ii;
3194
 
}
3195
 
 
3196
 
static const IP_ADAPTER_INDEX_MAP *
3197
 
get_interface_info (DWORD index, struct gc_arena *gc)
3198
 
{
3199
 
  const IP_INTERFACE_INFO *list = get_interface_info_list (gc);
3200
 
  if (list)
3201
 
    {
3202
 
      int i;
3203
 
      for (i = 0; i < list->NumAdapters; ++i)
3204
 
        {
3205
 
          const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
3206
 
          if (index == inter->Index)
3207
 
            return inter;
3208
 
        }
3209
 
    }
3210
 
  return NULL;
3211
 
}
3212
 
 
3213
 
/*
3214
 
 * Given an adapter index, return a pointer to the
3215
 
 * IP_ADAPTER_INFO structure for that adapter.
3216
 
 */
3217
 
 
3218
 
const IP_ADAPTER_INFO *
3219
 
get_adapter (const IP_ADAPTER_INFO *ai, DWORD index)
3220
 
{
3221
 
  if (ai && index != (DWORD)~0)
3222
 
    {
3223
 
      const IP_ADAPTER_INFO *a;
3224
 
 
3225
 
      /* find index in the linked list */
3226
 
      for (a = ai; a != NULL; a = a->Next)
3227
 
        {
3228
 
          if (a->Index == index)
3229
 
            return a;
3230
 
        }
3231
 
    }
3232
 
  return NULL;
3233
 
}
3234
 
 
3235
 
const IP_ADAPTER_INFO *
3236
 
get_adapter_info (DWORD index, struct gc_arena *gc)
3237
 
{
3238
 
  return get_adapter (get_adapter_info_list (gc), index);
3239
 
}
3240
 
 
3241
 
static int
3242
 
get_adapter_n_ip_netmask (const IP_ADAPTER_INFO *ai)
3243
 
{
3244
 
  if (ai)
3245
 
    {
3246
 
      int n = 0;
3247
 
      const IP_ADDR_STRING *ip = &ai->IpAddressList;
3248
 
 
3249
 
      while (ip)
3250
 
        {
3251
 
          ++n;
3252
 
          ip = ip->Next;
3253
 
        }
3254
 
      return n;
3255
 
    }
3256
 
  else
3257
 
    return 0;
3258
 
}
3259
 
 
3260
 
static bool
3261
 
get_adapter_ip_netmask (const IP_ADAPTER_INFO *ai, const int n, in_addr_t *ip, in_addr_t *netmask)
3262
 
{
3263
 
  bool ret = false;
3264
 
  *ip = 0;
3265
 
  *netmask = 0;
3266
 
 
3267
 
  if (ai)
3268
 
    {
3269
 
      const IP_ADDR_STRING *iplist = &ai->IpAddressList;
3270
 
      int i = 0;
3271
 
 
3272
 
      while (iplist)
3273
 
        {
3274
 
          if (i == n)
3275
 
            break;
3276
 
          ++i;
3277
 
          iplist = iplist->Next;
3278
 
        }
3279
 
 
3280
 
      if (iplist)
3281
 
        {
3282
 
          const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
3283
 
          const char *ip_str = iplist->IpAddress.String;
3284
 
          const char *netmask_str = iplist->IpMask.String;
3285
 
          bool succeed1 = false;
3286
 
          bool succeed2 = false;
3287
 
 
3288
 
          if (ip_str && netmask_str && strlen (ip_str) && strlen (netmask_str))
3289
 
            {
3290
 
              *ip = getaddr (getaddr_flags, ip_str, 0, &succeed1, NULL);
3291
 
              *netmask = getaddr (getaddr_flags, netmask_str, 0, &succeed2, NULL);
3292
 
              ret = (succeed1 == true && succeed2 == true);
3293
 
            }
3294
 
        }
3295
 
    }
3296
 
 
3297
 
  return ret;
3298
 
}
3299
 
 
3300
 
static bool
3301
 
test_adapter_ip_netmask (const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask)
3302
 
{
3303
 
  if (ai)
3304
 
    {
3305
 
      in_addr_t ip_adapter = 0;
3306
 
      in_addr_t netmask_adapter = 0;
3307
 
      const bool status = get_adapter_ip_netmask (ai, 0, &ip_adapter, &netmask_adapter);
3308
 
      return (status && ip_adapter == ip && netmask_adapter == netmask);
3309
 
    }
3310
 
  else
3311
 
    return false;
3312
 
}
3313
 
 
3314
 
const IP_ADAPTER_INFO *
3315
 
get_tun_adapter (const struct tuntap *tt, const IP_ADAPTER_INFO *list)
3316
 
{
3317
 
  if (list && tt)
3318
 
    return get_adapter (list, tt->adapter_index);
3319
 
  else
3320
 
    return NULL;
3321
 
}
3322
 
 
3323
 
bool
3324
 
is_adapter_up (const struct tuntap *tt, const IP_ADAPTER_INFO *list)
3325
 
{
3326
 
  int i;
3327
 
  bool ret = false;
3328
 
 
3329
 
  const IP_ADAPTER_INFO *ai = get_tun_adapter (tt, list);
3330
 
 
3331
 
  if (ai)
3332
 
    {
3333
 
      const int n = get_adapter_n_ip_netmask (ai);
3334
 
 
3335
 
      /* loop once for every IP/netmask assigned to adapter */
3336
 
      for (i = 0; i < n; ++i)
3337
 
        {
3338
 
          in_addr_t ip, netmask;
3339
 
          if (get_adapter_ip_netmask (ai, i, &ip, &netmask))
3340
 
            {
3341
 
              if (tt->local && tt->adapter_netmask)
3342
 
                {
3343
 
                  /* wait for our --ifconfig parms to match the actual adapter parms */
3344
 
                  if (tt->local == ip && tt->adapter_netmask == netmask)
3345
 
                    ret = true;
3346
 
                }
3347
 
              else
3348
 
                {
3349
 
                  /* --ifconfig was not defined, maybe using a real DHCP server */
3350
 
                  if (ip && netmask)
3351
 
                    ret = true;
3352
 
                }
3353
 
            }
3354
 
        }
3355
 
    }
3356
 
  else
3357
 
    ret = true; /* this can occur when TAP adapter is bridged */
3358
 
 
3359
 
  return ret;
3360
 
}
3361
 
 
3362
 
bool
3363
 
is_ip_in_adapter_subnet (const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask)
3364
 
{
3365
 
  int i;
3366
 
  bool ret = false;
3367
 
 
3368
 
  if (highest_netmask)
3369
 
    *highest_netmask = 0;
3370
 
 
3371
 
  if (ai)
3372
 
    {
3373
 
      const int n = get_adapter_n_ip_netmask (ai);
3374
 
      for (i = 0; i < n; ++i)
3375
 
        {
3376
 
          in_addr_t adapter_ip, adapter_netmask;
3377
 
          if (get_adapter_ip_netmask (ai, i, &adapter_ip, &adapter_netmask))
3378
 
            {
3379
 
              if (adapter_ip && adapter_netmask && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
3380
 
                {
3381
 
                  if (highest_netmask && adapter_netmask > *highest_netmask)
3382
 
                    *highest_netmask = adapter_netmask;
3383
 
                  ret = true;
3384
 
                }
3385
 
            }
3386
 
        }
3387
 
    }
3388
 
  return ret;
3389
 
}
3390
 
 
3391
 
DWORD
3392
 
adapter_index_of_ip (const IP_ADAPTER_INFO *list,
3393
 
                     const in_addr_t ip,
3394
 
                     int *count,
3395
 
                     in_addr_t *netmask)
3396
 
{
3397
 
  struct gc_arena gc = gc_new ();
3398
 
  DWORD ret = ~0;
3399
 
  in_addr_t highest_netmask = 0;
3400
 
  bool first = true;
3401
 
 
3402
 
  if (count)
3403
 
    *count = 0;
3404
 
 
3405
 
  while (list)
3406
 
    {
3407
 
      in_addr_t hn;
3408
 
 
3409
 
      if (is_ip_in_adapter_subnet (list, ip, &hn))
3410
 
        {
3411
 
          if (first || hn > highest_netmask)
3412
 
            {
3413
 
              highest_netmask = hn;
3414
 
              if (count)
3415
 
                *count = 1;
3416
 
              ret = list->Index;
3417
 
              first = false;
3418
 
            }
3419
 
          else if (hn == highest_netmask)
3420
 
            {
3421
 
              if (count)
3422
 
                ++*count;
3423
 
            }
3424
 
        }
3425
 
      list = list->Next;
3426
 
    }
3427
 
 
3428
 
  dmsg (D_ROUTE_DEBUG, "DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d",
3429
 
       print_in_addr_t (ip, 0, &gc),
3430
 
       print_in_addr_t (highest_netmask, 0, &gc),
3431
 
       (int)ret,
3432
 
       count ? *count : -1);
3433
 
 
3434
 
  if (ret == ~0 && count)
3435
 
    *count = 0;
3436
 
 
3437
 
  if (netmask)
3438
 
    *netmask = highest_netmask;
3439
 
 
3440
 
  gc_free (&gc);
3441
 
  return ret;
3442
 
}
3443
 
 
3444
 
/*
3445
 
 * Given an adapter index, return true if the adapter
3446
 
 * is DHCP disabled.
3447
 
 */
3448
 
 
3449
 
#define DHCP_STATUS_UNDEF     0
3450
 
#define DHCP_STATUS_ENABLED   1
3451
 
#define DHCP_STATUS_DISABLED  2
3452
 
 
3453
 
static int
3454
 
dhcp_status (DWORD index)
3455
 
{
3456
 
  struct gc_arena gc = gc_new ();
3457
 
  int ret = DHCP_STATUS_UNDEF;
3458
 
  if (index != ~0)
3459
 
    {
3460
 
      const IP_ADAPTER_INFO *ai = get_adapter_info (index, &gc);
3461
 
 
3462
 
      if (ai)
3463
 
        {
3464
 
          if (ai->DhcpEnabled)
3465
 
            ret = DHCP_STATUS_ENABLED;
3466
 
          else
3467
 
            ret = DHCP_STATUS_DISABLED;
3468
 
        }
3469
 
    }
3470
 
  gc_free (&gc);
3471
 
  return ret;
3472
 
}
3473
 
 
3474
 
/*
3475
 
 * Delete all temporary address/netmask pairs which were added
3476
 
 * to adapter (given by index) by previous calls to AddIPAddress.
3477
 
 */
3478
 
static void
3479
 
delete_temp_addresses (DWORD index)
3480
 
{
3481
 
  struct gc_arena gc = gc_new ();
3482
 
  const IP_ADAPTER_INFO *a = get_adapter_info (index, &gc);
3483
 
 
3484
 
  if (a)
3485
 
    {
3486
 
      const IP_ADDR_STRING *ip = &a->IpAddressList;
3487
 
      while (ip)
3488
 
        {
3489
 
          DWORD status;
3490
 
          const DWORD context = ip->Context;
3491
 
 
3492
 
          if ((status = DeleteIPAddress ((ULONG) context)) == NO_ERROR)
3493
 
            {
3494
 
              msg (M_INFO, "Successfully deleted previously set dynamic IP/netmask: %s/%s",
3495
 
                   ip->IpAddress.String,
3496
 
                   ip->IpMask.String);
3497
 
            }
3498
 
          else
3499
 
            {
3500
 
              const char *empty = "0.0.0.0";
3501
 
              if (strcmp (ip->IpAddress.String, empty)
3502
 
                  || strcmp (ip->IpMask.String, empty))
3503
 
                msg (M_INFO, "NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
3504
 
                     ip->IpAddress.String,
3505
 
                     ip->IpMask.String,
3506
 
                     (unsigned int)status);
3507
 
            }
3508
 
          ip = ip->Next;
3509
 
        }
3510
 
    }
3511
 
  gc_free (&gc);
3512
 
}
3513
 
 
3514
 
/*
3515
 
 * Get interface index for use with IP Helper API functions.
3516
 
 */
3517
 
static DWORD
3518
 
get_adapter_index_method_1 (const char *guid)
3519
 
{
3520
 
  struct gc_arena gc = gc_new ();
3521
 
  ULONG index = ~0;
3522
 
  DWORD status;
3523
 
  wchar_t wbuf[256];
3524
 
  snwprintf (wbuf, SIZE (wbuf), L"\\DEVICE\\TCPIP_%S", guid);
3525
 
  wbuf [SIZE(wbuf) - 1] = 0;
3526
 
  if ((status = GetAdapterIndex (wbuf, &index)) != NO_ERROR)
3527
 
    index = ~0;
3528
 
  gc_free (&gc);
3529
 
  return index;
3530
 
}
3531
 
 
3532
 
static DWORD
3533
 
get_adapter_index_method_2 (const char *guid)
3534
 
{
3535
 
  struct gc_arena gc = gc_new ();
3536
 
  DWORD index = ~0;
3537
 
 
3538
 
  const IP_ADAPTER_INFO *list = get_adapter_info_list (&gc);
3539
 
 
3540
 
  while (list)
3541
 
    {
3542
 
      if (!strcmp (guid, list->AdapterName))
3543
 
        {
3544
 
          index = list->Index;
3545
 
          break;
3546
 
        }
3547
 
      list = list->Next;
3548
 
    }
3549
 
 
3550
 
  gc_free (&gc);
3551
 
  return index;
3552
 
}
3553
 
 
3554
 
static DWORD
3555
 
get_adapter_index (const char *guid)
3556
 
{
3557
 
  DWORD index;
3558
 
  index = get_adapter_index_method_1 (guid);
3559
 
  if (index == ~0)
3560
 
    index = get_adapter_index_method_2 (guid);
3561
 
  if (index == ~0)
3562
 
    msg (M_INFO, "NOTE: could not get adapter index for %s", guid);
3563
 
  return index;
3564
 
}
3565
 
 
3566
 
static DWORD
3567
 
get_adapter_index_flexible (const char *name) /* actual name or GUID */
3568
 
{
3569
 
  struct gc_arena gc = gc_new ();
3570
 
  DWORD index;
3571
 
  index = get_adapter_index_method_1 (name);
3572
 
  if (index == ~0)
3573
 
    index = get_adapter_index_method_2 (name);
3574
 
  if (index == ~0)
3575
 
    {
3576
 
      const struct tap_reg *tap_reg = get_tap_reg (&gc);
3577
 
      const struct panel_reg *panel_reg = get_panel_reg (&gc);
3578
 
      const char *guid = name_to_guid (name, tap_reg, panel_reg);
3579
 
      index = get_adapter_index_method_1 (guid);
3580
 
      if (index == ~0)
3581
 
        index = get_adapter_index_method_2 (guid);
3582
 
    }
3583
 
  if (index == ~0)
3584
 
    msg (M_INFO, "NOTE: could not get adapter index for name/GUID '%s'", name);
3585
 
  gc_free (&gc);
3586
 
  return index;
3587
 
}
3588
 
 
3589
 
/*
3590
 
 * Return a string representing a PIP_ADDR_STRING
3591
 
 */
3592
 
static const char *
3593
 
format_ip_addr_string (const IP_ADDR_STRING *ip, struct gc_arena *gc)
3594
 
{
3595
 
  struct buffer out = alloc_buf_gc (256, gc);
3596
 
  while (ip)
3597
 
    {
3598
 
      buf_printf (&out, "%s", ip->IpAddress.String);
3599
 
      if (strlen (ip->IpMask.String))
3600
 
        {
3601
 
          buf_printf (&out, "/");
3602
 
          buf_printf (&out, "%s", ip->IpMask.String);
3603
 
        }
3604
 
      buf_printf (&out, " ");
3605
 
      ip = ip->Next;
3606
 
    }
3607
 
  return BSTR (&out);
3608
 
}
3609
 
 
3610
 
/*
3611
 
 * Show info for a single adapter
3612
 
 */
3613
 
static void
3614
 
show_adapter (int msglev, const IP_ADAPTER_INFO *a, struct gc_arena *gc)
3615
 
{
3616
 
  msg (msglev, "%s", a->Description);
3617
 
  msg (msglev, "  Index = %d", (int)a->Index);
3618
 
  msg (msglev, "  GUID = %s", a->AdapterName);
3619
 
  msg (msglev, "  IP = %s", format_ip_addr_string (&a->IpAddressList, gc));
3620
 
  msg (msglev, "  MAC = %s", format_hex_ex (a->Address, a->AddressLength, 0, 1, ":", gc));
3621
 
  msg (msglev, "  GATEWAY = %s", format_ip_addr_string (&a->GatewayList, gc));
3622
 
  if (a->DhcpEnabled)
3623
 
    {
3624
 
      msg (msglev, "  DHCP SERV = %s", format_ip_addr_string (&a->DhcpServer, gc));
3625
 
      msg (msglev, "  DHCP LEASE OBTAINED = %s", time_string (a->LeaseObtained, 0, false, gc));
3626
 
      msg (msglev, "  DHCP LEASE EXPIRES  = %s", time_string (a->LeaseExpires, 0, false, gc));
3627
 
    }
3628
 
  if (a->HaveWins)
3629
 
    {
3630
 
      msg (msglev, "  PRI WINS = %s", format_ip_addr_string (&a->PrimaryWinsServer, gc));
3631
 
      msg (msglev, "  SEC WINS = %s", format_ip_addr_string (&a->SecondaryWinsServer, gc));
3632
 
    }
3633
 
 
3634
 
  {
3635
 
    const IP_PER_ADAPTER_INFO *pai = get_per_adapter_info (a->Index, gc);
3636
 
    if (pai)
3637
 
      {
3638
 
        msg (msglev, "  DNS SERV = %s", format_ip_addr_string (&pai->DnsServerList, gc));
3639
 
      }
3640
 
  }
3641
 
}
3642
 
 
3643
 
/*
3644
 
 * Show current adapter list
3645
 
 */
3646
 
void
3647
 
show_adapters (int msglev)
3648
 
{
3649
 
  struct gc_arena gc = gc_new ();
3650
 
  const IP_ADAPTER_INFO *ai = get_adapter_info_list (&gc);
3651
 
 
3652
 
  msg (msglev, "SYSTEM ADAPTER LIST");
3653
 
  if (ai)
3654
 
    {
3655
 
      const IP_ADAPTER_INFO *a;
3656
 
 
3657
 
      /* find index in the linked list */
3658
 
      for (a = ai; a != NULL; a = a->Next)
3659
 
        {
3660
 
          show_adapter (msglev, a, &gc);
3661
 
        }
3662
 
    }
3663
 
  gc_free (&gc);
3664
 
}
3665
 
 
3666
 
/*
3667
 
 * Set a particular TAP-Win32 adapter (or all of them if
3668
 
 * adapter_name == NULL) to allow it to be opened from
3669
 
 * a non-admin account.  This setting will only persist
3670
 
 * for the lifetime of the device object.
3671
 
 */
3672
 
 
3673
 
static void
3674
 
tap_allow_nonadmin_access_handle (const char *device_path, HANDLE hand)
3675
 
{
3676
 
  struct security_attributes sa;
3677
 
  BOOL status;
3678
 
 
3679
 
  if (!init_security_attributes_allow_all (&sa))
3680
 
    msg (M_ERR, "Error: init SA failed");
3681
 
 
3682
 
  status = SetKernelObjectSecurity (hand, DACL_SECURITY_INFORMATION, &sa.sd);
3683
 
  if (!status)
3684
 
    {
3685
 
      msg (M_ERRNO, "Error: SetKernelObjectSecurity failed on %s", device_path);
3686
 
    }
3687
 
  else
3688
 
    {
3689
 
      msg (M_INFO|M_NOPREFIX, "TAP-Win32 device: %s [Non-admin access allowed]", device_path);
3690
 
    }
3691
 
}
3692
 
 
3693
 
void
3694
 
tap_allow_nonadmin_access (const char *dev_node)
3695
 
{
3696
 
  struct gc_arena gc = gc_new ();
3697
 
  const struct tap_reg *tap_reg = get_tap_reg (&gc);
3698
 
  const struct panel_reg *panel_reg = get_panel_reg (&gc);
3699
 
  const char *device_guid = NULL;
3700
 
  HANDLE hand;
3701
 
  char actual_buffer[256];
3702
 
  char device_path[256];
3703
 
 
3704
 
  at_least_one_tap_win32 (tap_reg);
3705
 
 
3706
 
  if (dev_node)
3707
 
    {
3708
 
      /* Get the device GUID for the device specified with --dev-node. */
3709
 
      device_guid = get_device_guid (dev_node, actual_buffer, sizeof (actual_buffer), tap_reg, panel_reg, &gc);
3710
 
 
3711
 
      if (!device_guid)
3712
 
        msg (M_FATAL, "TAP-Win32 adapter '%s' not found", dev_node);
3713
 
 
3714
 
      /* Open Windows TAP-Win32 adapter */
3715
 
      openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
3716
 
                        USERMODEDEVICEDIR,
3717
 
                        device_guid,
3718
 
                        TAPSUFFIX);
3719
 
      
3720
 
      hand = CreateFile (
3721
 
                         device_path,
3722
 
                         MAXIMUM_ALLOWED,
3723
 
                         0, /* was: FILE_SHARE_READ */
3724
 
                         0,
3725
 
                         OPEN_EXISTING,
3726
 
                         FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
3727
 
                         0
3728
 
                         );
3729
 
 
3730
 
      if (hand == INVALID_HANDLE_VALUE)
3731
 
        msg (M_ERR, "CreateFile failed on TAP device: %s", device_path);
3732
 
 
3733
 
      tap_allow_nonadmin_access_handle (device_path, hand);
3734
 
      CloseHandle (hand);
3735
 
    }
3736
 
  else 
3737
 
    {
3738
 
      int device_number = 0;
3739
 
 
3740
 
      /* Try opening all TAP devices */
3741
 
      while (true)
3742
 
        {
3743
 
          device_guid = get_unspecified_device_guid (device_number, 
3744
 
                                                     actual_buffer, 
3745
 
                                                     sizeof (actual_buffer),
3746
 
                                                     tap_reg,
3747
 
                                                     panel_reg,
3748
 
                                                     &gc);
3749
 
 
3750
 
          if (!device_guid)
3751
 
            break;
3752
 
 
3753
 
          /* Open Windows TAP-Win32 adapter */
3754
 
          openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
3755
 
                            USERMODEDEVICEDIR,
3756
 
                            device_guid,
3757
 
                            TAPSUFFIX);
3758
 
 
3759
 
          hand = CreateFile (
3760
 
                             device_path,
3761
 
                             MAXIMUM_ALLOWED,
3762
 
                             0, /* was: FILE_SHARE_READ */
3763
 
                             0,
3764
 
                             OPEN_EXISTING,
3765
 
                             FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
3766
 
                             0
3767
 
                             );
3768
 
 
3769
 
          if (hand == INVALID_HANDLE_VALUE)
3770
 
            msg (M_WARN, "CreateFile failed on TAP device: %s", device_path);
3771
 
          else
3772
 
            {
3773
 
              tap_allow_nonadmin_access_handle (device_path, hand);
3774
 
              CloseHandle (hand);
3775
 
            }
3776
 
  
3777
 
          device_number++;
3778
 
        }
3779
 
    }
3780
 
  gc_free (&gc);
3781
 
}
3782
 
 
3783
 
/*
3784
 
 * DHCP release/renewal
3785
 
 */
3786
 
bool
3787
 
dhcp_release_by_adapter_index(const DWORD adapter_index)
3788
 
{
3789
 
  struct gc_arena gc = gc_new ();
3790
 
  bool ret = false;
3791
 
  const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (adapter_index, &gc);
3792
 
 
3793
 
  if (inter)
3794
 
    {
3795
 
      DWORD status = IpReleaseAddress ((IP_ADAPTER_INDEX_MAP *)inter);
3796
 
      if (status == NO_ERROR)
3797
 
        {
3798
 
          msg (D_TUNTAP_INFO, "TAP: DHCP address released");
3799
 
          ret = true;
3800
 
        }
3801
 
      else
3802
 
        msg (M_WARN, "NOTE: Release of DHCP-assigned IP address lease on TAP-Win32 adapter failed: %s (code=%u)",
3803
 
             strerror_win32 (status, &gc),
3804
 
             (unsigned int)status);
3805
 
    }
3806
 
 
3807
 
  gc_free (&gc);
3808
 
  return ret;
3809
 
}
3810
 
 
3811
 
static bool
3812
 
dhcp_release (const struct tuntap *tt)
3813
 
{
3814
 
  if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
3815
 
    return dhcp_release_by_adapter_index (tt->adapter_index);
3816
 
  else
3817
 
    return false;
3818
 
}
3819
 
 
3820
 
bool
3821
 
dhcp_renew_by_adapter_index (const DWORD adapter_index)
3822
 
{
3823
 
  struct gc_arena gc = gc_new ();
3824
 
  bool ret = false;
3825
 
  const IP_ADAPTER_INDEX_MAP *inter = get_interface_info (adapter_index, &gc);
3826
 
 
3827
 
  if (inter)
3828
 
    {
3829
 
      DWORD status = IpRenewAddress ((IP_ADAPTER_INDEX_MAP *)inter);
3830
 
      if (status == NO_ERROR)
3831
 
        {
3832
 
          msg (D_TUNTAP_INFO, "TAP: DHCP address renewal succeeded");
3833
 
          ret = true;
3834
 
        }
3835
 
      else
3836
 
        msg (M_WARN, "WARNING: Failed to renew DHCP IP address lease on TAP-Win32 adapter: %s (code=%u)",
3837
 
             strerror_win32 (status, &gc),
3838
 
             (unsigned int)status);
3839
 
    }
3840
 
  gc_free (&gc);
3841
 
  return ret;
3842
 
}
3843
 
 
3844
 
static bool
3845
 
dhcp_renew (const struct tuntap *tt)
3846
 
{
3847
 
  if (tt && tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ && tt->adapter_index != ~0)
3848
 
    return dhcp_renew_by_adapter_index (tt->adapter_index);
3849
 
  else
3850
 
    return false;
3851
 
}
3852
 
 
3853
 
/*
3854
 
 * netsh functions
3855
 
 */
3856
 
 
3857
 
static void
3858
 
netsh_command (const struct argv *a, int n)
3859
 
{
3860
 
  int i;
3861
 
  for (i = 0; i < n; ++i)
3862
 
    {
3863
 
      bool status;
3864
 
      openvpn_sleep (1);
3865
 
      netcmd_semaphore_lock ();
3866
 
      argv_msg_prefix (M_INFO, a, "NETSH");
3867
 
      status = openvpn_execve_check (a, NULL, 0, "ERROR: netsh command failed");
3868
 
      netcmd_semaphore_release ();
3869
 
      if (status)
3870
 
        return;
3871
 
      openvpn_sleep (4);
3872
 
    }
3873
 
  msg (M_FATAL, "NETSH: command failed");
3874
 
}
3875
 
 
3876
 
void
3877
 
ipconfig_register_dns (const struct env_set *es)
3878
 
{
3879
 
  struct argv argv;
3880
 
  bool status;
3881
 
  const char err[] = "ERROR: Windows ipconfig command failed";
3882
 
 
3883
 
  msg (D_TUNTAP_INFO, "Start net commands...");
3884
 
  netcmd_semaphore_lock ();
3885
 
 
3886
 
  argv_init (&argv);
3887
 
 
3888
 
  argv_printf (&argv, "%s%sc stop dnscache",
3889
 
               get_win_sys_path(),
3890
 
               WIN_NET_PATH_SUFFIX);
3891
 
  argv_msg (D_TUNTAP_INFO, &argv);
3892
 
  status = openvpn_execve_check (&argv, es, 0, err);
3893
 
  argv_reset(&argv);
3894
 
 
3895
 
  argv_printf (&argv, "%s%sc start dnscache",
3896
 
               get_win_sys_path(),
3897
 
               WIN_NET_PATH_SUFFIX);
3898
 
  argv_msg (D_TUNTAP_INFO, &argv);
3899
 
  status = openvpn_execve_check (&argv, es, 0, err);
3900
 
  argv_reset(&argv);
3901
 
 
3902
 
  argv_printf (&argv, "%s%sc /flushdns",
3903
 
               get_win_sys_path(),
3904
 
               WIN_IPCONFIG_PATH_SUFFIX);
3905
 
  argv_msg (D_TUNTAP_INFO, &argv);
3906
 
  status = openvpn_execve_check (&argv, es, 0, err);
3907
 
  argv_reset(&argv);
3908
 
 
3909
 
  argv_printf (&argv, "%s%sc /registerdns",
3910
 
               get_win_sys_path(),
3911
 
               WIN_IPCONFIG_PATH_SUFFIX);
3912
 
  argv_msg (D_TUNTAP_INFO, &argv);
3913
 
  status = openvpn_execve_check (&argv, es, 0, err);
3914
 
  argv_reset(&argv);
3915
 
 
3916
 
  netcmd_semaphore_release ();
3917
 
  msg (D_TUNTAP_INFO, "End net commands...");
3918
 
}
3919
 
 
3920
 
void
3921
 
ip_addr_string_to_array (in_addr_t *dest, int *dest_len, const IP_ADDR_STRING *src)
3922
 
{
3923
 
  int i = 0;
3924
 
  while (src)
3925
 
    {
3926
 
      const unsigned int getaddr_flags = GETADDR_HOST_ORDER;
3927
 
      const char *ip_str = src->IpAddress.String;
3928
 
      in_addr_t ip = 0;
3929
 
      bool succeed = false;
3930
 
 
3931
 
      if (i >= *dest_len)
3932
 
        break;
3933
 
      if (!ip_str || !strlen (ip_str))
3934
 
        break;
3935
 
 
3936
 
      ip = getaddr (getaddr_flags, ip_str, 0, &succeed, NULL);
3937
 
      if (!succeed)
3938
 
        break;
3939
 
      dest[i++] = ip;
3940
 
 
3941
 
      src = src->Next;
3942
 
    }
3943
 
  *dest_len = i;
3944
 
 
3945
 
#if 0
3946
 
 {
3947
 
   struct gc_arena gc = gc_new ();
3948
 
   msg (M_INFO, "ip_addr_string_to_array [%d]", *dest_len);
3949
 
   for (i = 0; i < *dest_len; ++i)
3950
 
     {
3951
 
       msg (M_INFO, "%s", print_in_addr_t (dest[i], 0, &gc));
3952
 
     }
3953
 
   gc_free (&gc);
3954
 
 }
3955
 
#endif
3956
 
}
3957
 
 
3958
 
static bool
3959
 
ip_addr_one_to_one (const in_addr_t *a1, const int a1len, const IP_ADDR_STRING *ias)
3960
 
{
3961
 
  in_addr_t a2[8];
3962
 
  int a2len = SIZE(a2);
3963
 
  int i;
3964
 
 
3965
 
  ip_addr_string_to_array (a2, &a2len, ias);
3966
 
  /*msg (M_INFO, "a1len=%d a2len=%d", a1len, a2len);*/
3967
 
  if (a1len != a2len)
3968
 
    return false;
3969
 
 
3970
 
  for (i = 0; i < a1len; ++i)
3971
 
    {
3972
 
      if (a1[i] != a2[i])
3973
 
        return false;
3974
 
    }
3975
 
  return true;
3976
 
}
3977
 
 
3978
 
static bool
3979
 
ip_addr_member_of (const in_addr_t addr, const IP_ADDR_STRING *ias)
3980
 
{
3981
 
  in_addr_t aa[8];
3982
 
  int len = SIZE(aa);
3983
 
  int i;
3984
 
 
3985
 
  ip_addr_string_to_array (aa, &len, ias);
3986
 
  for (i = 0; i < len; ++i)
3987
 
    {
3988
 
      if (addr == aa[i])
3989
 
        return true;
3990
 
    }
3991
 
  return false;
3992
 
}
3993
 
 
3994
 
static void
3995
 
netsh_ifconfig_options (const char *type,
3996
 
                        const in_addr_t *addr_list,
3997
 
                        const int addr_len,
3998
 
                        const IP_ADDR_STRING *current,
3999
 
                        const char *flex_name,
4000
 
                        const bool test_first)
4001
 
{
4002
 
  struct gc_arena gc = gc_new ();
4003
 
  struct argv argv = argv_new ();
4004
 
  bool delete_first = false;
4005
 
 
4006
 
  /* first check if we should delete existing DNS/WINS settings from TAP interface */
4007
 
  if (test_first)
4008
 
    {
4009
 
      if (!ip_addr_one_to_one (addr_list, addr_len, current))
4010
 
        delete_first = true;
4011
 
    }
4012
 
  else
4013
 
    delete_first = true;
4014
 
  
4015
 
  /* delete existing DNS/WINS settings from TAP interface */
4016
 
  if (delete_first)
4017
 
    {
4018
 
      argv_printf (&argv, "%s%sc interface ip delete %s %s all",
4019
 
                   get_win_sys_path(),
4020
 
                   NETSH_PATH_SUFFIX,
4021
 
                   type,
4022
 
                   flex_name);
4023
 
      netsh_command (&argv, 2);
4024
 
    }
4025
 
 
4026
 
  /* add new DNS/WINS settings to TAP interface */
4027
 
  {
4028
 
    int count = 0;
4029
 
    int i;
4030
 
    for (i = 0; i < addr_len; ++i)
4031
 
      {
4032
 
        if (delete_first || !test_first || !ip_addr_member_of (addr_list[i], current))
4033
 
          {
4034
 
            const char *fmt = count ?
4035
 
                "%s%sc interface ip add %s %s %s"
4036
 
              : "%s%sc interface ip set %s %s static %s";
4037
 
 
4038
 
            argv_printf (&argv, fmt,
4039
 
                         get_win_sys_path(),
4040
 
                         NETSH_PATH_SUFFIX,
4041
 
                         type,
4042
 
                         flex_name,
4043
 
                         print_in_addr_t (addr_list[i], 0, &gc));
4044
 
            netsh_command (&argv, 2);
4045
 
          
4046
 
            ++count;
4047
 
          }
4048
 
        else
4049
 
          {
4050
 
            msg (M_INFO, "NETSH: \"%s\" %s %s [already set]",
4051
 
                 flex_name,
4052
 
                 type,
4053
 
                 print_in_addr_t (addr_list[i], 0, &gc));
4054
 
          }
4055
 
      }
4056
 
  }
4057
 
 
4058
 
  argv_reset (&argv);
4059
 
  gc_free (&gc);
4060
 
}
4061
 
 
4062
 
static void
4063
 
init_ip_addr_string2 (IP_ADDR_STRING *dest, const IP_ADDR_STRING *src1, const IP_ADDR_STRING *src2)
4064
 
{
4065
 
  CLEAR (dest[0]);
4066
 
  CLEAR (dest[1]);
4067
 
  if (src1)
4068
 
    {
4069
 
      dest[0] = *src1;
4070
 
      dest[0].Next = NULL;
4071
 
    }
4072
 
  if (src2)
4073
 
    {
4074
 
      dest[1] = *src2;
4075
 
      dest[0].Next = &dest[1];
4076
 
      dest[1].Next = NULL;
4077
 
    }
4078
 
}
4079
 
 
4080
 
static void
4081
 
netsh_ifconfig (const struct tuntap_options *to,
4082
 
                const char *flex_name,
4083
 
                const in_addr_t ip,
4084
 
                const in_addr_t netmask,
4085
 
                const unsigned int flags)
4086
 
{
4087
 
  struct gc_arena gc = gc_new ();
4088
 
  struct argv argv = argv_new ();
4089
 
  const IP_ADAPTER_INFO *ai = NULL;
4090
 
  const IP_PER_ADAPTER_INFO *pai = NULL;
4091
 
 
4092
 
  if (flags & NI_TEST_FIRST)
4093
 
    {
4094
 
      const IP_ADAPTER_INFO *list = get_adapter_info_list (&gc);
4095
 
      const int index = get_adapter_index_flexible (flex_name);
4096
 
      ai = get_adapter (list, index);
4097
 
      pai = get_per_adapter_info (index, &gc);
4098
 
    }
4099
 
 
4100
 
  if (flags & NI_IP_NETMASK)
4101
 
    {
4102
 
      if (test_adapter_ip_netmask (ai, ip, netmask))
4103
 
        {
4104
 
          msg (M_INFO, "NETSH: \"%s\" %s/%s [already set]",
4105
 
               flex_name,
4106
 
               print_in_addr_t (ip, 0, &gc),
4107
 
               print_in_addr_t (netmask, 0, &gc));
4108
 
        }
4109
 
      else
4110
 
        {
4111
 
          /* example: netsh interface ip set address my-tap static 10.3.0.1 255.255.255.0 */
4112
 
          argv_printf (&argv, "%s%sc interface ip set address %s static %s %s",
4113
 
                       get_win_sys_path(),
4114
 
                       NETSH_PATH_SUFFIX,
4115
 
                       flex_name,
4116
 
                       print_in_addr_t (ip, 0, &gc),
4117
 
                       print_in_addr_t (netmask, 0, &gc));
4118
 
 
4119
 
          netsh_command (&argv, 4);
4120
 
        }
4121
 
    }
4122
 
 
4123
 
  /* set WINS/DNS options */
4124
 
  if (flags & NI_OPTIONS)
4125
 
    {
4126
 
      IP_ADDR_STRING wins[2];
4127
 
      CLEAR (wins[0]);
4128
 
      CLEAR (wins[1]);
4129
 
 
4130
 
      netsh_ifconfig_options ("dns",
4131
 
                              to->dns,
4132
 
                              to->dns_len,
4133
 
                              pai ? &pai->DnsServerList : NULL,
4134
 
                              flex_name,
4135
 
                              BOOL_CAST (flags & NI_TEST_FIRST));
4136
 
      if (ai && ai->HaveWins)
4137
 
        init_ip_addr_string2 (wins, &ai->PrimaryWinsServer, &ai->SecondaryWinsServer);
4138
 
 
4139
 
      netsh_ifconfig_options ("wins",
4140
 
                              to->wins,
4141
 
                              to->wins_len,
4142
 
                              ai ? wins : NULL,
4143
 
                              flex_name,
4144
 
                              BOOL_CAST (flags & NI_TEST_FIRST));
4145
 
    }
4146
 
  
4147
 
  argv_reset (&argv);
4148
 
  gc_free (&gc);
4149
 
}
4150
 
 
4151
 
static void
4152
 
netsh_enable_dhcp (const struct tuntap_options *to,
4153
 
                   const char *actual_name)
4154
 
{
4155
 
  struct argv argv;
4156
 
  argv_init (&argv);
4157
 
 
4158
 
  /* example: netsh interface ip set address my-tap dhcp */
4159
 
  argv_printf (&argv,
4160
 
              "%s%sc interface ip set address %s dhcp",
4161
 
               get_win_sys_path(),
4162
 
               NETSH_PATH_SUFFIX,
4163
 
               actual_name);
4164
 
 
4165
 
  netsh_command (&argv, 4);
4166
 
 
4167
 
  argv_reset (&argv);
4168
 
}
4169
 
 
4170
 
/*
4171
 
 * Return a TAP name for netsh commands.
4172
 
 */
4173
 
static const char *
4174
 
netsh_get_id (const char *dev_node, struct gc_arena *gc)
4175
 
{
4176
 
  const struct tap_reg *tap_reg = get_tap_reg (gc);
4177
 
  const struct panel_reg *panel_reg = get_panel_reg (gc);
4178
 
  struct buffer actual = alloc_buf_gc (256, gc);
4179
 
  const char *guid;
4180
 
 
4181
 
  at_least_one_tap_win32 (tap_reg);
4182
 
 
4183
 
  if (dev_node)
4184
 
    {
4185
 
      guid = get_device_guid (dev_node, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);
4186
 
    }
4187
 
  else
4188
 
    {
4189
 
      guid = get_unspecified_device_guid (0, BPTR (&actual), BCAP (&actual), tap_reg, panel_reg, gc);
4190
 
 
4191
 
      if (get_unspecified_device_guid (1, NULL, 0, tap_reg, panel_reg, gc)) /* ambiguous if more than one TAP-Win32 adapter */
4192
 
        guid = NULL;
4193
 
    }
4194
 
 
4195
 
  if (!guid)
4196
 
    return "NULL";         /* not found */
4197
 
  else if (strcmp (BPTR (&actual), "NULL"))
4198
 
    return BPTR (&actual); /* control panel name */
4199
 
  else
4200
 
    return guid;           /* no control panel name, return GUID instead */
4201
 
}
4202
 
 
4203
 
/*
4204
 
 * Called iteratively on TAP-Win32 wait-for-initialization polling loop
4205
 
 */
4206
 
void
4207
 
tun_standby_init (struct tuntap *tt)
4208
 
{
4209
 
  tt->standby_iter = 0;
4210
 
}
4211
 
 
4212
 
bool
4213
 
tun_standby (struct tuntap *tt)
4214
 
{
4215
 
  bool ret = true;
4216
 
  ++tt->standby_iter;
4217
 
  if (tt->options.ip_win32_type == IPW32_SET_ADAPTIVE)
4218
 
    {
4219
 
      if (tt->standby_iter == IPW32_SET_ADAPTIVE_TRY_NETSH)
4220
 
        {
4221
 
          msg (M_INFO, "NOTE: now trying netsh (this may take some time)");
4222
 
          netsh_ifconfig (&tt->options,
4223
 
                          tt->actual_name,
4224
 
                          tt->local,
4225
 
                          tt->adapter_netmask,
4226
 
                          NI_TEST_FIRST|NI_IP_NETMASK|NI_OPTIONS);
4227
 
        }
4228
 
      else if (tt->standby_iter >= IPW32_SET_ADAPTIVE_TRY_NETSH*2)
4229
 
        {
4230
 
          ret = false;
4231
 
        }
4232
 
    }
4233
 
  return ret;
4234
 
}
4235
 
 
4236
 
/*
4237
 
 * Convert DHCP options from the command line / config file
4238
 
 * into a raw DHCP-format options string.
4239
 
 */
4240
 
 
4241
 
static void
4242
 
write_dhcp_u8 (struct buffer *buf, const int type, const int data, bool *error)
4243
 
{
4244
 
  if (!buf_safe (buf, 3))
4245
 
    {
4246
 
      *error = true;
4247
 
      msg (M_WARN, "write_dhcp_u8: buffer overflow building DHCP options");
4248
 
      return;
4249
 
    }
4250
 
  buf_write_u8 (buf, type);
4251
 
  buf_write_u8 (buf, 1);
4252
 
  buf_write_u8 (buf, data);
4253
 
}
4254
 
 
4255
 
static void
4256
 
write_dhcp_u32_array (struct buffer *buf, const int type, const uint32_t *data, const unsigned int len, bool *error)
4257
 
{
4258
 
  if (len > 0)
4259
 
    {
4260
 
      int i;
4261
 
      const int size = len * sizeof (uint32_t);
4262
 
 
4263
 
      if (!buf_safe (buf, 2 + size))
4264
 
        {
4265
 
          *error = true;
4266
 
          msg (M_WARN, "write_dhcp_u32_array: buffer overflow building DHCP options");
4267
 
          return;
4268
 
        }
4269
 
      if (size < 1 || size > 255)
4270
 
        {
4271
 
          *error = true;
4272
 
          msg (M_WARN, "write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
4273
 
          return;
4274
 
        }
4275
 
      buf_write_u8 (buf, type);
4276
 
      buf_write_u8 (buf, size);
4277
 
      for (i = 0; i < len; ++i)
4278
 
        buf_write_u32 (buf, data[i]);
4279
 
    }
4280
 
}
4281
 
 
4282
 
static void
4283
 
write_dhcp_str (struct buffer *buf, const int type, const char *str, bool *error)
4284
 
{
4285
 
  const int len = strlen (str);
4286
 
  if (!buf_safe (buf, 2 + len))
4287
 
    {
4288
 
      *error = true;
4289
 
      msg (M_WARN, "write_dhcp_str: buffer overflow building DHCP options");
4290
 
      return;
4291
 
    }
4292
 
  if (len < 1 || len > 255)
4293
 
    {
4294
 
      *error = true;
4295
 
      msg (M_WARN, "write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes", str);
4296
 
      return;
4297
 
    }
4298
 
  buf_write_u8 (buf, type);
4299
 
  buf_write_u8 (buf, len);
4300
 
  buf_write (buf, str, len);
4301
 
}
4302
 
 
4303
 
static bool
4304
 
build_dhcp_options_string (struct buffer *buf, const struct tuntap_options *o)
4305
 
{
4306
 
  bool error = false;
4307
 
  if (o->domain)
4308
 
    write_dhcp_str (buf, 15, o->domain, &error);
4309
 
 
4310
 
  if (o->netbios_scope)
4311
 
    write_dhcp_str (buf, 47, o->netbios_scope, &error);
4312
 
 
4313
 
  if (o->netbios_node_type)
4314
 
    write_dhcp_u8 (buf, 46, o->netbios_node_type, &error);
4315
 
 
4316
 
  write_dhcp_u32_array (buf, 6, (uint32_t*)o->dns, o->dns_len, &error);
4317
 
  write_dhcp_u32_array (buf, 44, (uint32_t*)o->wins, o->wins_len, &error);
4318
 
  write_dhcp_u32_array (buf, 42, (uint32_t*)o->ntp, o->ntp_len, &error);
4319
 
  write_dhcp_u32_array (buf, 45, (uint32_t*)o->nbdd, o->nbdd_len, &error);
4320
 
 
4321
 
  /* the MS DHCP server option 'Disable Netbios-over-TCP/IP
4322
 
     is implemented as vendor option 001, value 002.
4323
 
     A value of 001 means 'leave NBT alone' which is the default */
4324
 
  if (o->disable_nbt)
4325
 
  {
4326
 
    if (!buf_safe (buf, 8))
4327
 
      {
4328
 
        msg (M_WARN, "build_dhcp_options_string: buffer overflow building DHCP options");
4329
 
        return false;
4330
 
      }
4331
 
    buf_write_u8 (buf,  43);
4332
 
    buf_write_u8 (buf,  6);  /* total length field */
4333
 
    buf_write_u8 (buf,  0x001);
4334
 
    buf_write_u8 (buf,  4);  /* length of the vendor specified field */
4335
 
    buf_write_u32 (buf, 0x002);
4336
 
  }
4337
 
  return !error;
4338
 
}
4339
 
 
4340
 
static void
4341
 
fork_dhcp_action (struct tuntap *tt)
4342
 
{
4343
 
  if (tt->options.dhcp_pre_release || tt->options.dhcp_renew)
4344
 
    {
4345
 
      struct gc_arena gc = gc_new ();
4346
 
      struct buffer cmd = alloc_buf_gc (256, &gc);
4347
 
      const int verb = 3;
4348
 
      const int pre_sleep = 1;
4349
 
  
4350
 
      buf_printf (&cmd, "openvpn --verb %d --tap-sleep %d", verb, pre_sleep);
4351
 
      if (tt->options.dhcp_pre_release)
4352
 
        buf_printf (&cmd, " --dhcp-pre-release");
4353
 
      if (tt->options.dhcp_renew)
4354
 
        buf_printf (&cmd, " --dhcp-renew");
4355
 
      buf_printf (&cmd, " --dhcp-internal %u", (unsigned int)tt->adapter_index);
4356
 
 
4357
 
      fork_to_self (BSTR (&cmd));
4358
 
      gc_free (&gc);
4359
 
    }
4360
 
}
4361
 
 
4362
 
void
4363
 
fork_register_dns_action (struct tuntap *tt)
4364
 
{
4365
 
  if (tt && tt->options.register_dns)
4366
 
    {
4367
 
      struct gc_arena gc = gc_new ();
4368
 
      struct buffer cmd = alloc_buf_gc (256, &gc);
4369
 
      const int verb = 3;
4370
 
 
4371
 
      buf_printf (&cmd, "openvpn --verb %d --register-dns --rdns-internal", verb);
4372
 
      fork_to_self (BSTR (&cmd));
4373
 
      gc_free (&gc);
4374
 
    }
4375
 
}
4376
 
 
4377
 
void
4378
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
4379
 
{
4380
 
  struct gc_arena gc = gc_new ();
4381
 
  char device_path[256];
4382
 
  const char *device_guid = NULL;
4383
 
  DWORD len;
4384
 
  bool dhcp_masq = false;
4385
 
  bool dhcp_masq_post = false;
4386
 
 
4387
 
  /*netcmd_semaphore_lock ();*/
4388
 
 
4389
 
  msg( M_INFO, "open_tun, tt->ipv6=%d", tt->ipv6 );
4390
 
 
4391
 
  if (tt->type == DEV_TYPE_NULL)
4392
 
    {
4393
 
      open_null (tt);
4394
 
      gc_free (&gc);
4395
 
      return;
4396
 
    }
4397
 
  else if (tt->type == DEV_TYPE_TAP || tt->type == DEV_TYPE_TUN)
4398
 
    {
4399
 
      ;
4400
 
    }
4401
 
  else
4402
 
    {
4403
 
      msg (M_FATAL|M_NOPREFIX, "Unknown virtual device type: '%s'", dev);
4404
 
    }
4405
 
 
4406
 
  /*
4407
 
   * Lookup the device name in the registry, using the --dev-node high level name.
4408
 
   */
4409
 
  {
4410
 
    const struct tap_reg *tap_reg = get_tap_reg (&gc);
4411
 
    const struct panel_reg *panel_reg = get_panel_reg (&gc);
4412
 
    char actual_buffer[256];
4413
 
 
4414
 
    at_least_one_tap_win32 (tap_reg);
4415
 
 
4416
 
    if (dev_node)
4417
 
      {
4418
 
        /* Get the device GUID for the device specified with --dev-node. */
4419
 
        device_guid = get_device_guid (dev_node, actual_buffer, sizeof (actual_buffer), tap_reg, panel_reg, &gc);
4420
 
 
4421
 
        if (!device_guid)
4422
 
          msg (M_FATAL, "TAP-Win32 adapter '%s' not found", dev_node);
4423
 
 
4424
 
        /* Open Windows TAP-Win32 adapter */
4425
 
        openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
4426
 
                          USERMODEDEVICEDIR,
4427
 
                          device_guid,
4428
 
                          TAPSUFFIX);
4429
 
 
4430
 
        tt->hand = CreateFile (
4431
 
                               device_path,
4432
 
                               GENERIC_READ | GENERIC_WRITE,
4433
 
                               0, /* was: FILE_SHARE_READ */
4434
 
                               0,
4435
 
                               OPEN_EXISTING,
4436
 
                               FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
4437
 
                               0
4438
 
                               );
4439
 
 
4440
 
        if (tt->hand == INVALID_HANDLE_VALUE)
4441
 
          msg (M_ERR, "CreateFile failed on TAP device: %s", device_path);
4442
 
      }
4443
 
    else 
4444
 
      {
4445
 
        int device_number = 0;
4446
 
 
4447
 
        /* Try opening all TAP devices until we find one available */
4448
 
        while (true)
4449
 
          {
4450
 
            device_guid = get_unspecified_device_guid (device_number, 
4451
 
                                                       actual_buffer, 
4452
 
                                                       sizeof (actual_buffer),
4453
 
                                                       tap_reg,
4454
 
                                                       panel_reg,
4455
 
                                                       &gc);
4456
 
 
4457
 
            if (!device_guid)
4458
 
              msg (M_FATAL, "All TAP-Win32 adapters on this system are currently in use.");
4459
 
 
4460
 
            /* Open Windows TAP-Win32 adapter */
4461
 
            openvpn_snprintf (device_path, sizeof(device_path), "%s%s%s",
4462
 
                              USERMODEDEVICEDIR,
4463
 
                              device_guid,
4464
 
                              TAPSUFFIX);
4465
 
 
4466
 
            tt->hand = CreateFile (
4467
 
                                   device_path,
4468
 
                                   GENERIC_READ | GENERIC_WRITE,
4469
 
                                   0, /* was: FILE_SHARE_READ */
4470
 
                                   0,
4471
 
                                   OPEN_EXISTING,
4472
 
                                   FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
4473
 
                                   0
4474
 
                                   );
4475
 
 
4476
 
            if (tt->hand == INVALID_HANDLE_VALUE)
4477
 
              msg (D_TUNTAP_INFO, "CreateFile failed on TAP device: %s", device_path);
4478
 
            else
4479
 
              break;
4480
 
        
4481
 
            device_number++;
4482
 
          }
4483
 
      }
4484
 
 
4485
 
    /* translate high-level device name into a device instance
4486
 
       GUID using the registry */
4487
 
    tt->actual_name = string_alloc (actual_buffer, NULL);
4488
 
  }
4489
 
 
4490
 
  msg (M_INFO, "TAP-WIN32 device [%s] opened: %s", tt->actual_name, device_path);
4491
 
  tt->adapter_index = get_adapter_index (device_guid);
4492
 
 
4493
 
  /* get driver version info */
4494
 
  {
4495
 
    ULONG info[3];
4496
 
    CLEAR (info);
4497
 
    if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_VERSION,
4498
 
                         &info, sizeof (info),
4499
 
                         &info, sizeof (info), &len, NULL))
4500
 
      {
4501
 
        msg (D_TUNTAP_INFO, "TAP-Win32 Driver Version %d.%d %s",
4502
 
             (int) info[0],
4503
 
             (int) info[1],
4504
 
             (info[2] ? "(DEBUG)" : ""));
4505
 
 
4506
 
      }
4507
 
    if (!(info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR))
4508
 
      msg (M_FATAL, "ERROR:  This version of " PACKAGE_NAME " requires a TAP-Win32 driver that is at least version %d.%d -- If you recently upgraded your " PACKAGE_NAME " distribution, a reboot is probably required at this point to get Windows to see the new driver.",
4509
 
           TAP_WIN32_MIN_MAJOR,
4510
 
           TAP_WIN32_MIN_MINOR);
4511
 
 
4512
 
    /* usage of numeric constants is ugly, but this is really tied to
4513
 
     * *this* version of the driver
4514
 
     */
4515
 
    if ( tt->ipv6 && tt->type == DEV_TYPE_TUN &&
4516
 
         info[0] == 9 && info[1] < 8)
4517
 
      {
4518
 
        msg( M_INFO, "WARNING:  Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode.  IPv6 will be disabled.  Upgrade to Tap-Win32 9.8 (2.2-beta3 release or later) or use TAP mode to get IPv6", (int) info[0], (int) info[1] );
4519
 
        tt->ipv6 = false;
4520
 
      }
4521
 
  }
4522
 
 
4523
 
  /* get driver MTU */
4524
 
  {
4525
 
    ULONG mtu;
4526
 
    if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_MTU,
4527
 
                         &mtu, sizeof (mtu),
4528
 
                         &mtu, sizeof (mtu), &len, NULL))
4529
 
      {
4530
 
        tt->post_open_mtu = (int) mtu;
4531
 
        msg (D_MTU_INFO, "TAP-Win32 MTU=%d", (int) mtu);
4532
 
      }
4533
 
  }
4534
 
 
4535
 
  /*
4536
 
   * Preliminaries for setting TAP-Win32 adapter TCP/IP
4537
 
   * properties via --ip-win32 dynamic or --ip-win32 adaptive.
4538
 
   */
4539
 
  if (tt->did_ifconfig_setup)
4540
 
    {
4541
 
      if (tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ)
4542
 
        {
4543
 
          /*
4544
 
           * If adapter is set to non-DHCP, set to DHCP mode.
4545
 
           */
4546
 
          if (dhcp_status (tt->adapter_index) == DHCP_STATUS_DISABLED)
4547
 
            netsh_enable_dhcp (&tt->options, tt->actual_name);
4548
 
          dhcp_masq = true;
4549
 
          dhcp_masq_post = true;
4550
 
        }
4551
 
      else if (tt->options.ip_win32_type == IPW32_SET_ADAPTIVE)
4552
 
        {
4553
 
          /*
4554
 
           * If adapter is set to non-DHCP, use netsh right away.
4555
 
           */
4556
 
          if (dhcp_status (tt->adapter_index) != DHCP_STATUS_ENABLED)
4557
 
            {
4558
 
              netsh_ifconfig (&tt->options,
4559
 
                              tt->actual_name,
4560
 
                              tt->local,
4561
 
                              tt->adapter_netmask,
4562
 
                              NI_TEST_FIRST|NI_IP_NETMASK|NI_OPTIONS);
4563
 
            }
4564
 
          else
4565
 
            {
4566
 
              dhcp_masq = true;
4567
 
            }
4568
 
        }
4569
 
    }
4570
 
 
4571
 
  /* set point-to-point mode if TUN device */
4572
 
 
4573
 
  if (tt->type == DEV_TYPE_TUN)
4574
 
    {
4575
 
      if (!tt->did_ifconfig_setup)
4576
 
        {
4577
 
          msg (M_FATAL, "ERROR: --dev tun also requires --ifconfig");
4578
 
        }
4579
 
 
4580
 
      if (tt->topology == TOP_SUBNET)
4581
 
        {
4582
 
          in_addr_t ep[3];
4583
 
          BOOL status;
4584
 
 
4585
 
          ep[0] = htonl (tt->local);
4586
 
          ep[1] = htonl (tt->local & tt->remote_netmask);
4587
 
          ep[2] = htonl (tt->remote_netmask);
4588
 
 
4589
 
          status = DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_TUN,
4590
 
                                    ep, sizeof (ep),
4591
 
                                    ep, sizeof (ep), &len, NULL);
4592
 
 
4593
 
          msg (status ? M_INFO : M_FATAL, "Set TAP-Win32 TUN subnet mode network/local/netmask = %s/%s/%s [%s]",
4594
 
               print_in_addr_t (ep[1], IA_NET_ORDER, &gc),
4595
 
               print_in_addr_t (ep[0], IA_NET_ORDER, &gc),
4596
 
               print_in_addr_t (ep[2], IA_NET_ORDER, &gc),
4597
 
               status ? "SUCCEEDED" : "FAILED");
4598
 
 
4599
 
        } else {
4600
 
 
4601
 
          in_addr_t ep[2];
4602
 
          ep[0] = htonl (tt->local);
4603
 
          ep[1] = htonl (tt->remote_netmask);
4604
 
 
4605
 
          if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_POINT_TO_POINT,
4606
 
                                ep, sizeof (ep),
4607
 
                                ep, sizeof (ep), &len, NULL))
4608
 
            msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
4609
 
        }
4610
 
    }
4611
 
 
4612
 
  /* should we tell the TAP-Win32 driver to masquerade as a DHCP server as a means
4613
 
     of setting the adapter address? */
4614
 
  if (dhcp_masq)
4615
 
    {
4616
 
      uint32_t ep[4];
4617
 
 
4618
 
      /* We will answer DHCP requests with a reply to set IP/subnet to these values */
4619
 
      ep[0] = htonl (tt->local);
4620
 
      ep[1] = htonl (tt->adapter_netmask);
4621
 
 
4622
 
      /* At what IP address should the DHCP server masquerade at? */
4623
 
      if (tt->type == DEV_TYPE_TUN)
4624
 
        {
4625
 
          if (tt->topology == TOP_SUBNET)
4626
 
            {
4627
 
              const in_addr_t netmask_inv = ~tt->remote_netmask;
4628
 
              ep[2] = netmask_inv ? htonl ((tt->local | netmask_inv) - 1) : 0;
4629
 
            }
4630
 
          else
4631
 
            ep[2] = htonl (tt->remote_netmask);
4632
 
 
4633
 
          if (tt->options.dhcp_masq_custom_offset)
4634
 
            msg (M_WARN, "WARNING: because you are using '--dev tun' mode, the '--ip-win32 dynamic [offset]' option is ignoring the offset parameter");
4635
 
        }
4636
 
      else
4637
 
        {
4638
 
          in_addr_t dsa; /* DHCP server addr */
4639
 
 
4640
 
          ASSERT (tt->type == DEV_TYPE_TAP);
4641
 
 
4642
 
          if (tt->options.dhcp_masq_offset < 0)
4643
 
            dsa = (tt->local | (~tt->adapter_netmask)) + tt->options.dhcp_masq_offset;
4644
 
          else
4645
 
            dsa = (tt->local & tt->adapter_netmask) + tt->options.dhcp_masq_offset;
4646
 
 
4647
 
          if (dsa == tt->local)
4648
 
            msg (M_FATAL, "ERROR: There is a clash between the --ifconfig local address and the internal DHCP server address -- both are set to %s -- please use the --ip-win32 dynamic option to choose a different free address from the --ifconfig subnet for the internal DHCP server", print_in_addr_t (dsa, 0, &gc));
4649
 
 
4650
 
          if ((tt->local & tt->adapter_netmask) != (dsa & tt->adapter_netmask))
4651
 
            msg (M_FATAL, "ERROR: --tap-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
4652
 
 
4653
 
          ep[2] = htonl (dsa);
4654
 
        }
4655
 
 
4656
 
      /* lease time in seconds */
4657
 
      ep[3] = (uint32_t) tt->options.dhcp_lease_time;
4658
 
 
4659
 
      ASSERT (ep[3] > 0);
4660
 
 
4661
 
#ifndef SIMULATE_DHCP_FAILED /* this code is disabled to simulate bad DHCP negotiation */
4662
 
      if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_DHCP_MASQ,
4663
 
                            ep, sizeof (ep),
4664
 
                            ep, sizeof (ep), &len, NULL))
4665
 
        msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a DeviceIoControl call to set TAP_IOCTL_CONFIG_DHCP_MASQ mode");
4666
 
 
4667
 
      msg (M_INFO, "Notified TAP-Win32 driver to set a DHCP IP/netmask of %s/%s on interface %s [DHCP-serv: %s, lease-time: %d]",
4668
 
           print_in_addr_t (tt->local, 0, &gc),
4669
 
           print_in_addr_t (tt->adapter_netmask, 0, &gc),
4670
 
           device_guid,
4671
 
           print_in_addr_t (ep[2], IA_NET_ORDER, &gc),
4672
 
           ep[3]
4673
 
           );
4674
 
 
4675
 
      /* user-supplied DHCP options capability */
4676
 
      if (tt->options.dhcp_options)
4677
 
        {
4678
 
          struct buffer buf = alloc_buf (256);
4679
 
          if (build_dhcp_options_string (&buf, &tt->options))
4680
 
            {
4681
 
              msg (D_DHCP_OPT, "DHCP option string: %s", format_hex (BPTR (&buf), BLEN (&buf), 0, &gc));
4682
 
              if (!DeviceIoControl (tt->hand, TAP_IOCTL_CONFIG_DHCP_SET_OPT,
4683
 
                                    BPTR (&buf), BLEN (&buf),
4684
 
                                    BPTR (&buf), BLEN (&buf), &len, NULL))
4685
 
                msg (M_FATAL, "ERROR: The TAP-Win32 driver rejected a TAP_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
4686
 
            }
4687
 
          else
4688
 
            msg (M_WARN, "DHCP option string not set due to error");
4689
 
          free_buf (&buf);
4690
 
        }
4691
 
#endif
4692
 
    }
4693
 
 
4694
 
  /* set driver media status to 'connected' */
4695
 
  {
4696
 
    ULONG status = TRUE;
4697
 
    if (!DeviceIoControl (tt->hand, TAP_IOCTL_SET_MEDIA_STATUS,
4698
 
                          &status, sizeof (status),
4699
 
                          &status, sizeof (status), &len, NULL))
4700
 
      msg (M_WARN, "WARNING: The TAP-Win32 driver rejected a TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
4701
 
  }
4702
 
 
4703
 
  /* possible wait for adapter to come up */
4704
 
  {
4705
 
    int s = tt->options.tap_sleep;
4706
 
    if (s > 0)
4707
 
      {
4708
 
        msg (M_INFO, "Sleeping for %d seconds...", s);
4709
 
        openvpn_sleep (s);
4710
 
      }
4711
 
  }
4712
 
 
4713
 
  /* possibly use IP Helper API to set IP address on adapter */
4714
 
  {
4715
 
    const DWORD index = tt->adapter_index;
4716
 
    
4717
 
    /* flush arp cache */
4718
 
    if (index != (DWORD)~0)
4719
 
      {
4720
 
        DWORD status;
4721
 
 
4722
 
        if ((status = FlushIpNetTable (index)) == NO_ERROR)
4723
 
          msg (M_INFO, "Successful ARP Flush on interface [%u] %s",
4724
 
               (unsigned int)index,
4725
 
               device_guid);
4726
 
        else
4727
 
          msg (D_TUNTAP_INFO, "NOTE: FlushIpNetTable failed on interface [%u] %s (status=%u) : %s",
4728
 
               (unsigned int)index,
4729
 
               device_guid,
4730
 
               (unsigned int)status,
4731
 
               strerror_win32 (status, &gc));
4732
 
      }
4733
 
 
4734
 
    /*
4735
 
     * If the TAP-Win32 driver is masquerading as a DHCP server
4736
 
     * make sure the TCP/IP properties for the adapter are
4737
 
     * set correctly.
4738
 
     */
4739
 
    if (dhcp_masq_post)
4740
 
      {
4741
 
        /* check dhcp enable status */
4742
 
        if (dhcp_status (index) == DHCP_STATUS_DISABLED)
4743
 
          msg (M_WARN, "WARNING: You have selected '--ip-win32 dynamic', which will not work unless the TAP-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'");
4744
 
 
4745
 
        /* force an explicit DHCP lease renewal on TAP adapter? */
4746
 
        if (tt->options.dhcp_pre_release)
4747
 
          dhcp_release (tt);
4748
 
        if (tt->options.dhcp_renew)
4749
 
          dhcp_renew (tt);
4750
 
      }
4751
 
    else
4752
 
      fork_dhcp_action (tt);
4753
 
 
4754
 
    if (tt->did_ifconfig_setup && tt->options.ip_win32_type == IPW32_SET_IPAPI)
4755
 
      {
4756
 
        DWORD status;
4757
 
        const char *error_suffix = "I am having trouble using the Windows 'IP helper API' to automatically set the IP address -- consider using other --ip-win32 methods (not 'ipapi')";
4758
 
 
4759
 
        /* couldn't get adapter index */
4760
 
        if (index == (DWORD)~0)
4761
 
          {
4762
 
            msg (M_FATAL, "ERROR: unable to get adapter index for interface %s -- %s",
4763
 
                 device_guid,
4764
 
                 error_suffix);
4765
 
          }
4766
 
 
4767
 
        /* check dhcp enable status */
4768
 
        if (dhcp_status (index) == DHCP_STATUS_DISABLED)
4769
 
          msg (M_WARN, "NOTE: You have selected (explicitly or by default) '--ip-win32 ipapi', which has a better chance of working correctly if the TAP-Win32 TCP/IP properties are set to 'Obtain an IP address automatically'");
4770
 
 
4771
 
        /* delete previously added IP addresses which were not
4772
 
           correctly deleted */
4773
 
        delete_temp_addresses (index);
4774
 
 
4775
 
        /* add a new IP address */
4776
 
        if ((status = AddIPAddress (htonl(tt->local),
4777
 
                                    htonl(tt->adapter_netmask),
4778
 
                                    index,
4779
 
                                    &tt->ipapi_context,
4780
 
                                    &tt->ipapi_instance)) == NO_ERROR)
4781
 
          msg (M_INFO, "Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
4782
 
               print_in_addr_t (tt->local, 0, &gc),
4783
 
               print_in_addr_t (tt->adapter_netmask, 0, &gc),
4784
 
               device_guid
4785
 
               );
4786
 
        else
4787
 
          msg (M_FATAL, "ERROR: AddIPAddress %s/%s failed on interface %s, index=%d, status=%u (windows error: '%s') -- %s",
4788
 
               print_in_addr_t (tt->local, 0, &gc),
4789
 
               print_in_addr_t (tt->adapter_netmask, 0, &gc),
4790
 
               device_guid,
4791
 
               (int)index,
4792
 
               (unsigned int)status,
4793
 
               strerror_win32 (status, &gc),
4794
 
               error_suffix);
4795
 
        tt->ipapi_context_defined = true;
4796
 
      }
4797
 
  }
4798
 
  /*netcmd_semaphore_release ();*/
4799
 
  gc_free (&gc);
4800
 
}
4801
 
 
4802
 
const char *
4803
 
tap_win32_getinfo (const struct tuntap *tt, struct gc_arena *gc)
4804
 
{
4805
 
  if (tt && tt->hand != NULL)
4806
 
    {
4807
 
      struct buffer out = alloc_buf_gc (256, gc);
4808
 
      DWORD len;
4809
 
      if (DeviceIoControl (tt->hand, TAP_IOCTL_GET_INFO,
4810
 
                           BSTR (&out), BCAP (&out),
4811
 
                           BSTR (&out), BCAP (&out),
4812
 
                           &len, NULL))
4813
 
        {
4814
 
          return BSTR (&out);
4815
 
        }
4816
 
    }
4817
 
  return NULL;
4818
 
}
4819
 
 
4820
 
void
4821
 
tun_show_debug (struct tuntap *tt)
4822
 
{
4823
 
  if (tt && tt->hand != NULL)
4824
 
    {
4825
 
      struct buffer out = alloc_buf (1024);
4826
 
      DWORD len;
4827
 
      while (DeviceIoControl (tt->hand, TAP_IOCTL_GET_LOG_LINE,
4828
 
                              BSTR (&out), BCAP (&out),
4829
 
                              BSTR (&out), BCAP (&out),
4830
 
                              &len, NULL))
4831
 
        {
4832
 
          msg (D_TAP_WIN32_DEBUG, "TAP-Win32: %s", BSTR (&out));
4833
 
        }
4834
 
      free_buf (&out);
4835
 
    }
4836
 
}
4837
 
 
4838
 
void
4839
 
close_tun (struct tuntap *tt)
4840
 
{
4841
 
  struct gc_arena gc = gc_new ();
4842
 
 
4843
 
  if (tt)
4844
 
    {
4845
 
      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
4846
 
        {
4847
 
          /* netsh interface ipv6 delete address \"%s\" %s */
4848
 
          const char * ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
4849
 
          msg( M_WARN, "TODO: remove IPv6 address %s", ifconfig_ipv6_local );
4850
 
        }
4851
 
#if 1
4852
 
      if (tt->ipapi_context_defined)
4853
 
        {
4854
 
          DWORD status;
4855
 
          if ((status = DeleteIPAddress (tt->ipapi_context)) != NO_ERROR)
4856
 
            {
4857
 
              msg (M_WARN, "Warning: DeleteIPAddress[%u] failed on TAP-Win32 adapter, status=%u : %s",
4858
 
                   (unsigned int)tt->ipapi_context,
4859
 
                   (unsigned int)status,
4860
 
                   strerror_win32 (status, &gc));
4861
 
            }
4862
 
        }
4863
 
#endif
4864
 
 
4865
 
      if (tt->options.dhcp_release)
4866
 
        dhcp_release (tt);
4867
 
 
4868
 
      if (tt->hand != NULL)
4869
 
        {
4870
 
          dmsg (D_WIN32_IO_LOW, "Attempting CancelIO on TAP-Win32 adapter");
4871
 
          if (!CancelIo (tt->hand))
4872
 
            msg (M_WARN | M_ERRNO, "Warning: CancelIO failed on TAP-Win32 adapter");
4873
 
        }
4874
 
 
4875
 
      dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped read event on TAP-Win32 adapter");
4876
 
      overlapped_io_close (&tt->reads);
4877
 
 
4878
 
      dmsg (D_WIN32_IO_LOW, "Attempting close of overlapped write event on TAP-Win32 adapter");
4879
 
      overlapped_io_close (&tt->writes);
4880
 
 
4881
 
      if (tt->hand != NULL)
4882
 
        {
4883
 
          dmsg (D_WIN32_IO_LOW, "Attempting CloseHandle on TAP-Win32 adapter");
4884
 
          if (!CloseHandle (tt->hand))
4885
 
            msg (M_WARN | M_ERRNO, "Warning: CloseHandle failed on TAP-Win32 adapter");
4886
 
        }
4887
 
 
4888
 
      if (tt->actual_name)
4889
 
        free (tt->actual_name);
4890
 
 
4891
 
      clear_tuntap (tt);
4892
 
      free (tt);
4893
 
    }
4894
 
  gc_free (&gc);
4895
 
}
4896
 
 
4897
 
/*
4898
 
 * Convert --ip-win32 constants between index and ascii form.
4899
 
 */
4900
 
 
4901
 
struct ipset_names {
4902
 
  const char *short_form;
4903
 
};
4904
 
 
4905
 
/* Indexed by IPW32_SET_x */
4906
 
static const struct ipset_names ipset_names[] = {
4907
 
  {"manual"},
4908
 
  {"netsh"},
4909
 
  {"ipapi"},
4910
 
  {"dynamic"},
4911
 
  {"adaptive"}
4912
 
};
4913
 
 
4914
 
int
4915
 
ascii2ipset (const char* name)
4916
 
{
4917
 
  int i;
4918
 
  ASSERT (IPW32_SET_N == SIZE (ipset_names));
4919
 
  for (i = 0; i < IPW32_SET_N; ++i)
4920
 
    if (!strcmp (name, ipset_names[i].short_form))
4921
 
      return i;
4922
 
  return -1;
4923
 
}
4924
 
 
4925
 
const char *
4926
 
ipset2ascii (int index)
4927
 
{
4928
 
  ASSERT (IPW32_SET_N == SIZE (ipset_names));
4929
 
  if (index < 0 || index >= IPW32_SET_N)
4930
 
    return "[unknown --ip-win32 type]";
4931
 
  else
4932
 
    return ipset_names[index].short_form;
4933
 
}
4934
 
 
4935
 
const char *
4936
 
ipset2ascii_all (struct gc_arena *gc)
4937
 
{
4938
 
  struct buffer out = alloc_buf_gc (256, gc);
4939
 
  int i;
4940
 
 
4941
 
  ASSERT (IPW32_SET_N == SIZE (ipset_names));
4942
 
  for (i = 0; i < IPW32_SET_N; ++i)
4943
 
    {
4944
 
      if (i)
4945
 
        buf_printf(&out, " ");
4946
 
      buf_printf(&out, "[%s]", ipset2ascii(i));
4947
 
    }
4948
 
  return BSTR (&out);
4949
 
}
4950
 
 
4951
 
#else /* generic */
4952
 
 
4953
 
void
4954
 
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
4955
 
{
4956
 
  open_tun_generic (dev, dev_type, dev_node, false, true, tt);
4957
 
}
4958
 
 
4959
 
void
4960
 
close_tun (struct tuntap* tt)
4961
 
{
4962
 
  if (tt)
4963
 
    {
4964
 
      close_tun_generic (tt);
4965
 
      free (tt);
4966
 
    }
4967
 
}
4968
 
 
4969
 
int
4970
 
write_tun (struct tuntap* tt, uint8_t *buf, int len)
4971
 
{
4972
 
  return write (tt->fd, buf, len);
4973
 
}
4974
 
 
4975
 
int
4976
 
read_tun (struct tuntap* tt, uint8_t *buf, int len)
4977
 
{
4978
 
  return read (tt->fd, buf, len);
4979
 
}
4980
 
 
4981
 
#endif