Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 405937 | Differences between
and this patch

Collapse All | Expand All

(-)openvpn-2.2.2_unpatched//ChangeLog.IPv6 (+440 lines)
Line 0 Link Here
1
Do 31. Dez 15:32:40 CET 2009 Gert Doering
2
3
  * Basic IPv6 p2mp functionality implemented
4
5
  * new options:
6
     - server-ipv6
7
     - ifconfig-ipv6
8
     - ifconfig-ipv6-pool
9
     - route-ipv6
10
     - iroute-ipv6
11
12
  * modules touched:
13
     - init.c: init & setup IPv6 route list & add/delete IPv6 routes
14
     - tun.c: add "ifconfig" and "route" handling for IPv6
15
     - multi.c: IPv6 ifconfig-pool assignments
16
		put to route-hash table
17
		push to client
18
     - pool.c: extend pools to handle IPv4+IPv6, and also return IPv6 address
19
	       IPv6 address saved to file if ifconfig-pool-persist is set
20
	       (but ignored on read due to the way pools work)
21
     - mroute.c: handle reading src/dst addresses from IPv6 packets
22
		 (so multi.c can check against route-hash table)
23
		 handle printing of IPv6 mroute_addr structure
24
     - helper.c: implement "server-ipv6" macro (->ifconfig-ipv6, pool, ...)
25
     - options.c: implement all the new options
26
		  add helper functions for IPv6 address handling
27
     - forward.c: tell do_route() about IPv6 routes
28
     - route.c:   handle IPv6 route lists + route option lists
29
		  extend add_routes() to do IPv4 + IPv6 route lists
30
		  extend delete_routes() to do IPv4 + IPv6 route lists
31
		  implement add_route_ipv6(), delete_route_ipv6() to call
32
		  system-dependend external program to do the work
33
     - push.c:    handle pushing of "ifconfig-ipv6" option
34
     - socket.c:  helper function to check & print IPv6 address strings
35
36
  * known issues:
37
     - operating system support on all but Linux (ifconfig, route)
38
     - route-ipv6 gateway handling
39
     - iroute-ipv6 not implemented
40
     - TAP support: ifconfig, routing (route needs gateway!)
41
42
  * release as patch 20091231-1
43
44
Thu Dec 31 17:02:08 CET 2009
45
46
  * NetBSD port (NetBSD 3.1 on Sparc64)
47
48
  * mroute.c, socket.c: make byte/word access to in6_addr more portable
49
50
  * tun.c: fix IPv6 ifconfig arguments on NetBSD
51
52
    still doesn't work on NetBSD 3.1, "ifconfig tun0 inet6..." errors with
53
54
    ifconfig: SIOCAIFADDR: Address family not supported by protocol family
55
56
    (sys/net/if_tun.c, needs to be revision 1.80 or later, NetBSD PR 32944,
57
    included in NetBSD 4.0 and up)
58
59
60
Fri Jan  1 14:07:15 CET 2010
61
62
  * FreeBSD port (FreeBSD 6.3-p12 on i386)
63
64
  * tun.c: implement IPv6 ifconfig setting for FreeBSD
65
66
  * route.c: fix %s/%s argument to IPv6 route add/delete command for *BSD
67
68
  * TEST SUCCESS: FreeBSD 6.3-p12, server-ipv6, route-ipv6, ccd/iroute-ipv6
69
70
  * multi.c: implement setting and deleting of iroute-ipv6 
71
             (multi_add_iroutes(), multi_del_iroutes())
72
  * mroute.c: add mroute_helper_add_iroute6(), mroute_helper_del_iroute6()
73
  * mroute.h: add prototypes, increase MR_HELPER_NET_LEN to 129 (/0.../128)
74
  * multi.c: zeroize host part of IPv6 iroutes in multi_learn_in6_addr()
75
  * mroute.c: implement mroute_addr_mask_host_bits() for IPv6
76
77
  * TEST SUCCESS: Linux 2.6.30 (Gentoo)/iproute2, server-ipv6, ccd/iroute-ipv6
78
79
  * TEST SUCCESS: Linux 2.6.30 (Gentoo)/ifconfig, client-ipv6
80
81
  * TEST FAIL: NetBSD 5.0, IPv6 client
82
     - "ifconfig tun0 .../64" does not create a "connected" route
83
     - adding routes fails
84
85
     --> more work to do here.
86
87
  * release as patch 20100101-1
88
89
  * TEST FAIL: 
90
      FreeBSD 6.3-p12 server "--topology subnet"
91
      Linux/ifconfig client
92
    - BSD sends ICMP6 neighbor solicitations, which are ignored by Linux
93
    - server tun interface is not in p2p mode, client tun interface *is*
94
95
  * TEST SUCCESS: non-ipv6 enabled client -> "--server-ipv6" server
96
    (warnings in the log file, but no malfunctions)
97
98
99
Sat Jan  2 19:48:35 CET 2010
100
101
  * tun.c: change "ipv6_support()", do not turn off tt->ipv6 unconditionally
102
    if we don't know about OS IPv6 support - just log warning
103
104
  * tun.c: implement "ifconfig inet6" setting for MacOS X / Darwin
105
106
  * route.c: split *BSD system dependent part of add/delete_route_ipv6() 
107
             into FreeBSD/Dragonfly and NetBSD/Darwin/OpenBSD variants 
108
             ("2001:db8::/64" vs. "2001:db8:: --prefixlen 64").
109
110
  * tun.c: on MacOS X, NetBSD and OpenBSD, explicitely set on-link route
111
112
  * TEST SUCCESS: MacOS X, client-ipv6 with route-ipv6
113
114
115
Sun Jan  3 10:55:31 CET 2010
116
117
  * route.c: NetBSD fails with "-iface tun0", needs gateway address
118
    (assume that the same syntax is needed for OpenBSD)
119
120
  * route.h: introduce "remote_endpoint_ipv6" into "struct route_ipv6_list"
121
122
  * init.c: pass "ifconfig_ipv6_remote" as gateway to init_route_ipv6_list()
123
124
  * route.c: 
125
    - init_route_ipv6(): use "remote_endpoint_ipv6" as IPv6 gateway address
126
                         if no gateway was specified explicitely
127
128
    - init_route_ipv6_list(): fill in "remote_endpoint_ipv6", if parseable
129
130
    - get rid of "GATEWAY-LESS ROUTE6" warning
131
132
  * route.c, add_route_ipv6()
133
    - explicitely clear host bits of base address, to be able to more 
134
      easily set up "connected" /64 routes on NetBSD+Darwin
135
136
    - split system-dependent part between Darwin and NetBSD/OpenBSD
137
      (Darwin can use "-iface tun0", NetBSD/OpenBSD get gateway address)
138
139
    - change Solaris comments from "known-broken" to "unknown"
140
141
  * tun.c: rework NetBSD tunnel initialization and tun_read() / tun_write()
142
    to work the same way OpenBSD and NetBSD do - tunnel is put into 
143
    "multi-af" mode, and all packet read/write activity is prepended by 
144
    a 32 bit value specifying the address family.
145
146
  * TEST SUCCESS: NetBSD 5.0/Sparc64: client-ipv6 with route-ipv6
147
148
  * TEST SUCCESS: MacOS X 10.5: client-ipv6 with route-ipv6
149
150
  * (RE-)TEST SUCCESS: Linux/iproute2: server-ipv6
151
                       Linux/ifconfig: client-ipv6
152
                       FreeBSD 6.3: server-ipv6
153
154
  * release as patch 20100103-1
155
156
  * options.c: document all new options in "--help"
157
158
  * tun.c: fix typo in Solaris-specific section
159
160
  * socket.h, socket.c: change u_int32_t to uint32_t 
161
    (Solaris - and all the rest of the code uses "uintNN" anyway)
162
163
Mon Jan  4 17:46:58 CET 2010
164
165
  * socket.c: rework add_in6_addr() to use 32-bit access to struct in6_addr
166
    (Solaris has no 16-bit values in union, but this is more elegant as well)
167
168
  * tun.c: fix "ifconfig inet6" command for Solaris
169
170
  * tun.c: make sure "tun0 inet6" is unplumbed first, cleanup leftovers
171
172
  * route.c: add routes with "metric 0" on solaris, otherwise they just
173
    don't work (someone who understands Solaris might want to fix this).
174
175
  * Solaris "sort of" works now - ifconfig works, route add does not give
176
    errors, "netstat -rn" looks right, but packets are discarded unless
177
    the routes are installed with "metric 0".  So we just use "metric 0"...
178
179
  * CAVEAT: Solaris "ifconfig ... preferred" interferes with source address
180
    selection.  So if there are any active IPv6 interfaces configured with 
181
    "preferred", packets leaving out the tunnel will use the wrong source
182
    IPv6 address.  Not fixable from within OpenVPN.
183
184
  * CAVEAT2: Solaris insists on doing DHCPv6 on tun0 interfaces by default,
185
    so DHCPv6 solicitation packets will be seen.  Since the server end has
186
    no idea what to do with them, they are a harmless nuisance.  Fixable
187
    on the Solaris side via "ndpd.conf" (see ``man ifconfig'').
188
189
  * release as patch 20100104-1
190
191
Fri Jan  8 10:00:50 CET 2010
192
193
  * import into git repository
194
195
  * options.c: add sanity checks for most typical error cases
196
    (--ifconfig-ipv6-pool configured with no --ifconfig-ipv6, etc)
197
198
  * options.c: modify get_ipv6_addr() to be more flexible about netbits
199
    (optional now, default to /64) and to return the address-without-netbits
200
    string now (-> for options that want the IPv6 address in printable
201
    form, but without /nn)
202
203
  * options.c: modify --ifconfig-ipv6 to optionally accept /netbits,
204
    you can do now "ifconfig-ipv6 2001:df8::1/64 2001:df8::2" or just
205
    "ifconfig-ipv6 2001:df8::5 2001:df8::7", defaulting to /64
206
207
  * options.h: add necessary structure elements for --ifconfig-ipv6-push
208
209
  * options.c: implement "parse options" side of --ifconfig-ipv6-push
210
211
Tue Jan 12 22:42:09 CET 2010
212
213
  * tun.c: in TARGET_NETBSD #ifdef, distinguish between "old" code
214
    (IPv4 only, but unmodified read/write) and "new" code (multi-af, 
215
    extra 32 bit AF on read/write of the tun interface) - pre-4.0
216
    NetBSD systems don't have TUNSIFHEAD, no way to have common code.
217
218
  * TEST SUCCESS: NetBSD 5.0/Sparc64: client-ipv6 with route-ipv6 (v4+v6)
219
220
  * TEST SUCCESS: NetBSD 3.1/Sparc64: client-ipv6 with route-ipv6 (v4-only)
221
222
Thu Jan 14 15:41:50 CET 2010
223
224
  * multi.c: if "--ifconfig-push" is used together with "--ifconfig-ipv6-pool"
225
    and no "--ifconfig-ipv6-push" is seen, issue warning - the current
226
    implementation of pools has IPv6 tied to IPv4, so if v4 does not use
227
    the pool, it breaks for IPv6.  Not a *big* problem (since there is 
228
    enough v6, just give those users a static v6 address as well), but needs
229
    to be pointed out clearly.
230
231
  * release as patch 20100114-1
232
233
Tue Feb 16 14:43:28 CET 2010
234
235
  * options.c: print "IPv6 payload patch" release date in "--version"
236
237
  * tun.c: undo change to init_tun() (moving "bool tun" and call to
238
    "is_tun_p2p()" further up) - it wasn't needed and breaks "make check"
239
240
  * git stuff: rebase on David Sommerseth's openvpn-testing git tree
241
242
  * release as patch 20100216-1
243
244
Fri Feb 26 19:59:01 CET 2010
245
246
  * init.c: initialize tuntap->ipv6 in do_init_tun() (to make sure it's
247
    always initialized early-enough, independent of the sequence of
248
    do_ifconfig()/open_tun() [see ifconfig_order() in tun.h])
249
250
  * tun.c, init.c: remove "bool ipv6" argument to tuncfg(), open_tun()
251
    and open_tun_generic() - obsoleted by previous change
252
253
  * tun.c: remove ipv6_support() - original purpose was unclear, and all
254
    current platforms (except linux-very-old) fully support IPv6 now :-)
255
256
  * tun.c: initial implementation of "netsh" IPv6-ifconfig for Win32
257
258
  * RE-TEST SUCCESS: Linux/i386/ifconfig, client-tun/net30, v4+v6
259
260
Sun Feb 28 17:05:57 CET 2010
261
262
  * tun.c: NetBSD dependent part: correct destroying/re-creation of tun dev
263
264
  * tun.c: move adding of "connected" IPv6 prefix to new helper function,
265
           add_route_connected_v6_net()
266
267
  * RE-TEST SUCCESS: NetBSD 5.0/Sparc64, client-tun/net30, v4+v6
268
269
  * RE-TEST SUCCESS: NetBSD 3.1/Sparc64: client-tun/net30, v4-only
270
271
  * RE-TEST SUCCESS: Linux/i386/iproute2: server-tun/net30, v4+v6
272
273
  * tun.c: add #ifdef TARGET_DARWIN block for *_tun() functions, to
274
           be able to modify close_tun() for unconfiguring IPv6
275
276
  * tun.c: on close_tun() on MacOS X, need to de-configure "lo0" route for
277
           configured IPv6 address
278
279
  * RE-TEST SUCCESS: MacOS X (10.5)/i386: client-tun/net30, v4+v6
280
281
  * route.c: implement ipv6 route adding / deletion via "netsh" for WIN32
282
283
  * TEST FAIL: Windows XP fails, because the tun/tap driver does not
284
    forward IPv6 frames kernel->userland if in "tun" mode
285
286
  * options.c: set IPv6 version to 20100228-1
287
288
  * release as patch 20100228-1
289
290
Sun Mar  7 19:17:33 CET 2010
291
292
  * options.c: set IPv6 version to 20100307-1
293
294
  * TODO.IPv6: add note about OpenBSD TODO (#16)
295
296
  * route.c: set (and remove) "magic next hop" fe80::8 for IPv6 routes on
297
    Win32
298
299
  * install-win32/settings.in: bump TAP driver version from 9.6 to 9.7
300
    and TAP_RELDATE to "07/03/2010"
301
302
  * tap-win32/proto.h: add data types and definitions needed for IPv6
303
304
  * tap-win32/types.h: add m_UserToTap_IPv6 ethernet header for IPv6 packets
305
306
  * tap-win32/tapdrvr.c: implement support for IPv6 in TUN mode:
307
     - IPv6 packets User->OS need correct ether type
308
     - IPv6 packets OS->User get correctly forwarded
309
     - IPv6 neighbour discovery packets for "fe80::8" (magic address
310
       installed as route-nexthop by OpenVPN.exe) get answered locally
311
312
  * TEST SUCCESS: WindowsXP/32bit: client-tun/net30, v4+v6
313
314
  * tun.c: if IPv6 requested in TUN mode, and TUN/TAP driver version
315
    is older than 9.7, log warning and disable IPv6 (won't work anyway).
316
317
  * release as patch 20100307-1
318
319
Sat Jul 10 14:37:52 CEST 2010
320
321
  * TEST SUCCESS: point-to-point tun mode with --ifconfig-ipv6 between
322
                  Solaris10/sparc and Linux (Michal Ludvig)
323
    (using the whiteboard tun driver on Solaris, otherwise "no IPv6")
324
325
Sun Aug  8 12:30:44 CEST 2010
326
327
  * route.c: split NetBSD and OpenBSD parts of add_route_ipv6() and
328
             delete_route_ipv6(), implement OpenBSD variant
329
             (needs "-prefixlen nn" while NetBSD uses "/nn")
330
331
  * tun.c: implement IPv6 ifconfig for OpenBSD
332
333
  * tun.c: destroy tunX interface at tun_close() on OpenBSD (cleanup)
334
335
  * TEST SUCCESS: OpenBSD 4.7: client-tun/net30, v4+v6
336
337
Thu Sep  2 21:18:32 CEST 2010
338
339
  * tun.c: the TAP binary in 2.2-beta3 has the IPv6 related changes, but
340
    the version number is 9.8 now -> check for 9.8, not 9.7
341
342
Wed Sep 22 22:20:37 CEST 2010
343
344
  * tun.c: bugfix for Linux/iproute2/"topology subnet".  Works :-)
345
346
  * TEST SUCCESS: Linux/ifconfig: client-tun/net30+subnet, v4+v6
347
348
  * TEST SUCCESS: Linux/iproute2: client-tun/net30+subnet, v4+v6
349
350
  * options.c: tag as 20100922-1 so "allmerged" users can see IPv6 change
351
352
Fri Sep 24 17:57:41 CEST 2010
353
354
  * TEST SUCCESS: Linux/<both>: client-tap, v4+v6, ping6 on connected addr
355
356
  * TEST FAIL: Linux/<both>: client-tap, v6, route6 (gateway missing)
357
358
Do 21. Okt 19:36:49 CEST 2010
359
360
  * t_client.sh.in: cherrypick commit f25fe91a40aa3f and 6f1e61b41be52 
361
    (proper exit codes to signal "SKIP" if we do not want to run)
362
363
So 16. Jan 17:25:23 CET 2011
364
365
  * tun.c, route.c: cherrypick 121755c2cb4891f and f0eac1a5979096c67
366
    (TAP driver and "topology subnet" support for Solaris)
367
368
  * tun.c: add IPv6 configuration for TAP interfaces (<device>:1 inet6)
369
370
  * tun.c: on close_tun on Solaris, unplumb IPv6 TUN or TAP interfaces
371
372
  * TEST SUCCESS: OpenSolaris: client-tun, v4+v6
373
    TEST SUCCESS: OpenSolaris: client-tap, v4+v6, ping6 on connected addr
374
    TEST FAIL: OpenSolaris: client-tap, v6, route6 (gateway missing)
375
376
So 24. Apr 16:51:45 CEST 2011
377
378
  * rebase to "beta2.2" branch (at 2.2RC2 tag)
379
380
  * mroute.c: remove mroute_helper_lock/_unlock() calls for IPv6
381
  * socket.c: remove locking with L_INET_NTOA mutex
382
      (all the threading stuff got removed by David Sommerseth for 2.2)
383
384
  * mroute.c: remove duplicate mroute_helper_add_iroute6() and
385
              mroute_helper_del_iroute6() - "git rebase" artefact
386
387
  * ChangeLog.IPv6 and TODO.IPv6: add to commit
388
389
  * options.c: tag as 20110424-2 (2.2RC2)
390
391
  * TEST SUCCESS: Linux/ifconfig: client-tun/net30+subnet, v4+v6
392
393
  * TEST SUCCESS: Linux/iproute2: client-tun/net30+subnet, v4+v6
394
395
Thu Apr 28 19:10:01 CEST 2011
396
397
  * rebase to "origin/release/2.2" branch (at v2.2.0 tag)
398
399
Thu May 19 20:51:12 CEST 2011
400
401
  * include Windows "netsh add" -> "netsh set ... store=active" patch from
402
    Seth Mos, to fix restart problems on Windows due to persistant addresses
403
404
  * TEST SUCCESS: Windows XP SP3: client-tun/net30, v4+v6
405
406
Sat May 21 17:03:20 CEST 2011
407
408
  * tun.c: Solaris cleanup (use CLEAR() to zero-out "ifr")
409
410
  * tun.c: Windows cleanup: remove route and IPv6 address on disconnect
411
412
  * route.c, route.h: remove "static" from delete_route_ipv6(), needed
413
    for ipv6-route cleanup on disconnect
414
415
  * TEST SUCCESS: Windows XP SP3: client-tun/net30, v4+v6
416
417
  * TEST SUCCESS: Windows 7 Home Premium: client-tun/net30, v4+v6
418
419
So 22. Mai 14:46:12 CEST 2011
420
421
  * Tony Lim: removing routes fails on windows if certain bits are set
422
    in the "host part" (others are silently ignored) -->
423
424
  * route.c: create print_in6_addr_netbits_only() helper, call from 
425
    add_route_ipv6() and delete_route_ipv6() to get only network part
426
    of route-to-be-modified
427
428
  * route.c: set 'store=active' on adding routes on WIN32 as well (Tony Lim)
429
430
  * options.c: bump IPv6 release to 20110522-1
431
432
  * TEST SUCCESS: Linux/iproute2: client-tun/net30+subnet, v4+v6
433
434
  * TEST SUCCESS: Windows XP SP3: client-tun/net30, v4+v6
435
436
  * TEST SUCCESS: Windows 7 Home Premium: client-tun/net30, v4+v6
437
438
  * TEST SUCCESS: OpenBSD 4.7: client-tun/net30, v4+v6
439
    TEST FAIL: OpenBSD 4.7: client-tun/subnet, v4
440
    (seems to be due to "topology subnet has just not been implemented yet")
(-)openvpn-2.2.2_unpatched//README.IPv6 (+8 lines)
Line 0 Link Here
1
This is an experimentally patched version of OpenVPN 2.1 with IPv6
2
payload support.
3
4
Go here for release notes and documentation:
5
6
  http://www.greenie.net/ipv6/openvpn.html
7
8
Gert Doering, 31.12.2009
(-)openvpn-2.2.2_unpatched//TODO.IPv6 (+153 lines)
Line 0 Link Here
1
known issues for IPv6 payload support in OpenVPN
2
-----------------------------------------------
3
4
1.) "--topology subnet" doesn't work together with IPv6 payload on FreeBSD
5
    (verified for FreeBSD server, Linux/ifconfig client, problems 
6
    with ICMP6 neighbor solicitations from BSD not being answered by Linux)
7
8
2.) NetBSD IPv6 support doesn't work
9
    ("connected" route is not auto-created, "route-ipv6" adding fails)
10
11
    * fixed, 3.1.10 *
12
13
3.) route deletion for IPv6 routes is not yet done
14
15
    * fixed for configured routes, 3.1.10 *
16
    * missing for manual-ifconfig-connected (NetBSD, Darwin, Win32)
17
      * fixed for Win32, 22.5.2011
18
19
4.) do "ifconfig tun0 inet6 unplumb"  or "ifconfig tun0 destroy" for
20
    Solaris, *BSD, ... at program termination time, to clean up leftovers
21
    (unless tunnel persistance is desired).
22
23
    For Solaris, only the "ipv6 tun0" is affected, for the *BSDs all tun0
24
    stay around.
25
26
4a.) deconfigure IPv6 on tun interface on session termination, otherwise
27
    one could end up with something like this (on NetBSD):
28
29
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
30
        inet 10.9.0.18 -> 10.9.0.17 netmask 0xffffffff
31
        inet6 fe80::a00:20ff:fece:d299%tun0 ->  prefixlen 64 scopeid 0x3
32
        inet6 2001:608:4:eff::2000:3 ->  prefixlen 64
33
        inet6 2001:608:4:eff::1:3 ->  prefixlen 64
34
35
    (pool was changed, previous address still active on tun0, breakage)
36
37
    * semi-fixed for NetBSD, 28.2.10, always do tun0 destroy / tun0 create
38
      before actual ifconfig -- tunnel still lingers after OpenVPN quits
39
40
4b.) verify this - on FreeBSD, tun0 is auto-destroyed if created by
41
     opening /dev/tun (and lingers if created by "ifconfig tun0 create")
42
43
     -> use for persistant tunnels on not-linux?
44
45
5.) add new option "ifconfig-ipv6-push"
46
    (per-client static IPv6 assignment, -> radiusplugin, etc)
47
48
    * implemented, 14.1.10 *
49
50
6.) add new option "route-ipv6-gateway"
51
52
7.) add "full" gateway handling for IPv6 in route.c 
53
    (right now, the routes are just sent down the tun interface, if the
54
    operating system in questions supports that, without care for the
55
    gateway address - which does not work for gateways that are supposed
56
    to point elsewhere.  Also, it doesn't work for TAP interfaces.
57
58
8.) full IPv6 support for TAP interfaces 
59
    (main issue should be routes+gateway - and testing :-) )
60
61
    test 2010/09/24: TAP itself works on linux/ifconfig+iproute2, but 
62
    route-via-tap doesn't work at all (route points to "tap0" which fails)
63
64
17:51:14.075412 fe:ab:6e:c5:53:71 > 33:33:ff:00:00:01, ethertype IPv6 (0x86dd), length 86: 2001:608:4:a053::1:0 > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has 2001:608:4:a001::1, length 32
65
66
    how is iroute-via-tap supposed to work??
67
68
9.) verify that iroute-ipv6 and route-ipv6 interact in the same way as
69
    documented for iroute/route:
70
71
    A's subnet, OpenVPN must push this route to all clients
72
    EXCEPT for A, since the subnet is already owned by A.
73
    OpenVPN accomplishes this by not
74
    not pushing a route to a client
75
    if it matches one of the client's iroutes.
76
77
10.) extend "ifconfig-ipv6" to handle specification of /netbits, pushing
78
    of /netbits, and correctly ifconfig'ing this
79
    (default, if not specified: /64)
80
81
11.) do not add ipv6-routes if tun-ipv6 is not set - complain instead
82
83
     * done * 12.1.10
84
85
12.) handle incoming [::] and [fe80:...] packets in tun-p2mp MULTI mode
86
     (most likely those are DAD packets)
87
     silently ignore DAD?  
88
        Or accept-and-forward iff (multicast && client2client)?
89
     handle NS/NA
90
91
13.) from Martin List-Petersen:
92
93
	One thing, and I guess this requires modifications in
94
	network-manager-openvpn: It also works, BUT ignores "push
95
	route-ipv6-gateway" and "push route-ipv6 ...." (obviously routes pushed
96
	from the server) entirely.
97
98
14.) from ##openvpn-discussion:
99
100
	new features should be #ifdef'ed
101
102
	(check whether this is feasible at all)
103
104
15.) IPv6 related environment variables
105
106
	- document all of them in openvpn.8
107
	- make sure that all existing IPv4 stuff has IPv6 counterparts
108
109
16.) OpenBSD
110
	- implement ifconfig/route for IPv6
111
	- revert ifconfig/open_tun order to "normal" (separate commit!!!)
112
	  (openvpn-devel, Subject: OpenBSD)
113
	- test
114
115
17.) client-option (Elwood)
116
	- ignore-v6-push-options yes/no
117
	- ignore-v6-route-push  ("as for IPv4 routes")
118
119
18.) fail-save?  "what if 'ip -6 addr add' fails" -> fail, or fallback to v4?
120
	(-> recomment setting "ignore-v6-push-options yes")
121
122
19.) safety check: if connecting over IPv6 (v6 transport) and the pushed
123
     route-ipv6 network encompasses the server IPv6 address, make sure 
124
     we at least log a warning (until we can fiddle with external routing
125
     to make this work correctly).
126
127
20.) show "route add" / "route delete" commands for IPv6 in log file
128
     (we show the "ifconfig" commands, so why not the routes?)
129
130
     2010-08-07: this is a null-feature - it's already there, but with
131
                 different debug level (M_INFO vs. D_ROUTE) so user 
132
                 didn't notice
133
134
21.) enable ipv6-only server operations
135
      - decouple ipv6 pool handling from ipv4 pool
136
      - make sure Rest of OpenVPN doesn't assume "there will always be IPv4"
137
138
22.) implement --learn-address for IPv6
139
140
23.) FreeBSD 8 seems to require explicit setting of the "ifconfig" IPv6
141
     route, while FreeBSD 6+7 don't --> more testing, and code fix
142
143
     workaround for the time being: just add
144
145
	server-ipv6 2001:608:4:a051::/64
146
	route-ipv6 2001:608:4:a051::/64
147
148
    to the config
149
150
    (problem + workaround applies both to tun and tap style devices)
151
152
24.) implement link-local IPv6 addresses
153
     (OSPFv3 over TUN/multipoint does not work right now)
(-)openvpn-2.2.2_unpatched//forward.c (-1 / +2 lines)
Lines 262-268 Link Here
262
static void
262
static void
263
check_add_routes_action (struct context *c, const bool errors)
263
check_add_routes_action (struct context *c, const bool errors)
264
{
264
{
265
  do_route (&c->options, c->c1.route_list, c->c1.tuntap, c->plugins, c->c2.es);
265
  do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
266
	    c->c1.tuntap, c->plugins, c->c2.es);
266
  update_time ();
267
  update_time ();
267
  event_timeout_clear (&c->c2.route_wakeup);
268
  event_timeout_clear (&c->c2.route_wakeup);
268
  event_timeout_clear (&c->c2.route_wakeup_expire);
269
  event_timeout_clear (&c->c2.route_wakeup_expire);
(-)openvpn-2.2.2_unpatched//helper.c (+49 lines)
Lines 142-147 Link Here
142
142
143
#if P2MP
143
#if P2MP
144
#if P2MP_SERVER
144
#if P2MP_SERVER
145
146
  /* 
147
   *
148
   * HELPER DIRECTIVE for IPv6
149
   *
150
   * server-ipv6 2001:db8::/64
151
   *
152
   * EXPANDS TO:
153
   *
154
   * tun-ipv6
155
   * push "tun-ipv6"
156
   * ifconfig-ipv6 2001:db8::1 2001:db8::2
157
   * if !nopool: 
158
   *   ifconfig-ipv6-pool 2001:db8::1:0/64
159
   * 
160
   */
161
   if ( o->server_ipv6_defined )
162
     {
163
	if ( ! o->server_defined )
164
	  {
165
	    msg (M_USAGE, "--server-ipv6 must be used together with --server");
166
	  }
167
	if ( o->server_flags & SF_NOPOOL )
168
	  {
169
	    msg( M_USAGE, "--server-ipv6 is incompatible with 'nopool' option" );
170
	  }
171
	if ( o->ifconfig_ipv6_pool_defined )
172
	  {
173
	    msg( M_USAGE, "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
174
	  }
175
176
        /* local ifconfig is "base address + 1" and "+2" */
177
	o->ifconfig_ipv6_local = 
178
		print_in6_addr( add_in6_addr( o->server_network_ipv6, 1), 0, &o->gc );
179
	o->ifconfig_ipv6_remote = 
180
		print_in6_addr( add_in6_addr( o->server_network_ipv6, 2), 0, &o->gc );
181
182
	/* pool starts at "base address + 0x10000" */
183
	ASSERT( o->server_netbits_ipv6 < 96 );		/* want 32 bits */
184
	o->ifconfig_ipv6_pool_defined = true;
185
	o->ifconfig_ipv6_pool_base = 
186
		add_in6_addr( o->server_network_ipv6, 0x10000 );
187
	o->ifconfig_ipv6_pool_netbits = o->server_netbits_ipv6;
188
189
	o->tun_ipv6 = true;
190
191
	push_option( o, "tun-ipv6", M_USAGE );
192
     }
193
145
  /*
194
  /*
146
   *
195
   *
147
   * HELPER DIRECTIVE:
196
   * HELPER DIRECTIVE:
(-)openvpn-2.2.2_unpatched//init.c (-7 / +58 lines)
Lines 843-849 Link Here
843
	msg (M_FATAL|M_OPTERR,
843
	msg (M_FATAL|M_OPTERR,
844
	     "options --mktun or --rmtun should only be used together with --dev");
844
	     "options --mktun or --rmtun should only be used together with --dev");
845
      tuncfg (options->dev, options->dev_type, options->dev_node,
845
      tuncfg (options->dev, options->dev_type, options->dev_node,
846
	      options->tun_ipv6, options->persist_mode,
846
	      options->persist_mode,
847
	      options->username, options->groupname, &options->tuntap_options);
847
	      options->username, options->groupname, &options->tuntap_options);
848
      if (options->persist_mode && options->lladdr)
848
      if (options->persist_mode && options->lladdr)
849
        set_lladdr(options->dev, options->lladdr, NULL);
849
        set_lladdr(options->dev, options->lladdr, NULL);
Lines 1066-1071 Link Here
1066
{
1066
{
1067
  if (c->options.routes && !c->c1.route_list)
1067
  if (c->options.routes && !c->c1.route_list)
1068
    c->c1.route_list = new_route_list (c->options.max_routes, &c->gc);
1068
    c->c1.route_list = new_route_list (c->options.max_routes, &c->gc);
1069
  if (c->options.routes_ipv6 && !c->c1.route_ipv6_list)
1070
    c->c1.route_ipv6_list = new_route_ipv6_list (c->options.max_routes, &c->gc);
1069
}
1071
}
1070
1072
1071
1073
Lines 1108-1113 Link Here
1108
    }
1110
    }
1109
}
1111
}
1110
1112
1113
static void
1114
do_init_route_ipv6_list (const struct options *options,
1115
		    struct route_ipv6_list *route_ipv6_list,
1116
		    bool fatal,
1117
		    struct env_set *es)
1118
{
1119
  const char *gw = NULL;
1120
  int dev = dev_type_enum (options->dev, options->dev_type);
1121
  int metric = 0;
1122
1123
  if (dev != DEV_TYPE_TUN )
1124
    msg( M_WARN, "IPv6 routes on TAP devices are going to fail on some platforms (need gateway spec)" );	/* TODO-GERT */
1125
1126
  gw = options->ifconfig_ipv6_remote;		/* default GW = remote end */
1127
#if 0					/* not yet done for IPv6 - TODO!*/
1128
  if ( options->route_ipv6_default_gateway )		/* override? */
1129
    gw = options->route_ipv6_default_gateway;
1130
#endif
1131
1132
  if (options->route_default_metric)
1133
    metric = options->route_default_metric;
1134
1135
  if (!init_route_ipv6_list (route_ipv6_list,
1136
			options->routes_ipv6,
1137
			gw,
1138
			metric,
1139
			es))
1140
    {
1141
      if (fatal)
1142
	openvpn_exit (OPENVPN_EXIT_STATUS_ERROR);	/* exit point */
1143
    }
1144
  else
1145
    {
1146
      /* copy routes to environment */
1147
      setenv_routes_ipv6 (es, route_ipv6_list);
1148
    }
1149
}
1150
1151
1111
/*
1152
/*
1112
 * Called after all initialization has been completed.
1153
 * Called after all initialization has been completed.
1113
 */
1154
 */
Lines 1172-1183 Link Here
1172
void
1213
void
1173
do_route (const struct options *options,
1214
do_route (const struct options *options,
1174
	  struct route_list *route_list,
1215
	  struct route_list *route_list,
1216
	  struct route_ipv6_list *route_ipv6_list,
1175
	  const struct tuntap *tt,
1217
	  const struct tuntap *tt,
1176
	  const struct plugin_list *plugins,
1218
	  const struct plugin_list *plugins,
1177
	  struct env_set *es)
1219
	  struct env_set *es)
1178
{
1220
{
1179
  if (!options->route_noexec && route_list)
1221
  if (!options->route_noexec && ( route_list || route_ipv6_list ) )
1180
    add_routes (route_list, tt, ROUTE_OPTION_FLAGS (options), es);
1222
    add_routes (route_list, route_ipv6_list, tt, ROUTE_OPTION_FLAGS (options), es);
1181
1223
1182
  if (plugin_defined (plugins, OPENVPN_PLUGIN_ROUTE_UP))
1224
  if (plugin_defined (plugins, OPENVPN_PLUGIN_ROUTE_UP))
1183
    {
1225
    {
Lines 1234-1244 Link Here
1234
			   c->options.topology,
1276
			   c->options.topology,
1235
			   c->options.ifconfig_local,
1277
			   c->options.ifconfig_local,
1236
			   c->options.ifconfig_remote_netmask,
1278
			   c->options.ifconfig_remote_netmask,
1279
			   c->options.ifconfig_ipv6_local,
1280
			   c->options.ifconfig_ipv6_remote,
1237
			   addr_host (&c->c1.link_socket_addr.local),
1281
			   addr_host (&c->c1.link_socket_addr.local),
1238
			   addr_host (&c->c1.link_socket_addr.remote),
1282
			   addr_host (&c->c1.link_socket_addr.remote),
1239
			   !c->options.ifconfig_nowarn,
1283
			   !c->options.ifconfig_nowarn,
1240
			   c->c2.es);
1284
			   c->c2.es);
1241
1285
1286
  /* flag tunnel for IPv6 config if --tun-ipv6 is set */
1287
  c->c1.tuntap->ipv6 = c->options.tun_ipv6;
1288
1242
  init_tun_post (c->c1.tuntap,
1289
  init_tun_post (c->c1.tuntap,
1243
		 &c->c2.frame,
1290
		 &c->c2.frame,
1244
		 &c->options.tuntap_options);
1291
		 &c->options.tuntap_options);
Lines 1270-1275 Link Here
1270
      /* parse and resolve the route option list */
1317
      /* parse and resolve the route option list */
1271
      if (c->options.routes && c->c1.route_list && c->c2.link_socket)
1318
      if (c->options.routes && c->c1.route_list && c->c2.link_socket)
1272
	do_init_route_list (&c->options, c->c1.route_list, &c->c2.link_socket->info, false, c->c2.es);
1319
	do_init_route_list (&c->options, c->c1.route_list, &c->c2.link_socket->info, false, c->c2.es);
1320
      if (c->options.routes_ipv6 && c->c1.route_ipv6_list )
1321
	do_init_route_ipv6_list (&c->options, c->c1.route_ipv6_list, false, c->c2.es);
1273
1322
1274
      /* do ifconfig */
1323
      /* do ifconfig */
1275
      if (!c->options.ifconfig_noexec
1324
      if (!c->options.ifconfig_noexec
Lines 1286-1292 Link Here
1286
1335
1287
      /* open the tun device */
1336
      /* open the tun device */
1288
      open_tun (c->options.dev, c->options.dev_type, c->options.dev_node,
1337
      open_tun (c->options.dev, c->options.dev_type, c->options.dev_node,
1289
		c->options.tun_ipv6, c->c1.tuntap);
1338
		c->c1.tuntap);
1290
1339
1291
      /* set the hardware address */
1340
      /* set the hardware address */
1292
      if (c->options.lladdr)
1341
      if (c->options.lladdr)
Lines 1315-1321 Link Here
1315
1364
1316
      /* possibly add routes */
1365
      /* possibly add routes */
1317
      if (!c->options.route_delay_defined)
1366
      if (!c->options.route_delay_defined)
1318
	do_route (&c->options, c->c1.route_list, c->c1.tuntap, c->plugins, c->c2.es);
1367
	do_route (&c->options, c->c1.route_list, c->c1.route_ipv6_list,
1368
		  c->c1.tuntap, c->plugins, c->c2.es);
1319
1369
1320
      /*
1370
      /*
1321
       * Did tun/tap driver give us an MTU?
1371
       * Did tun/tap driver give us an MTU?
Lines 1389-1396 Link Here
1389
#endif
1439
#endif
1390
1440
1391
	  /* delete any routes we added */
1441
	  /* delete any routes we added */
1392
	  if (c->c1.route_list)
1442
	  if (c->c1.route_list || c->c1.route_ipv6_list )
1393
	    delete_routes (c->c1.route_list, c->c1.tuntap, ROUTE_OPTION_FLAGS (&c->options), c->c2.es);
1443
	    delete_routes (c->c1.route_list, c->c1.route_ipv6_list,
1444
			   c->c1.tuntap, ROUTE_OPTION_FLAGS (&c->options), c->c2.es);
1394
1445
1395
	  /* actually close tun/tap device based on --down-pre flag */
1446
	  /* actually close tun/tap device based on --down-pre flag */
1396
	  if (!c->options.down_pre)
1447
	  if (!c->options.down_pre)
(-)openvpn-2.2.2_unpatched//init.h (+1 lines)
Lines 63-68 Link Here
63
63
64
void do_route (const struct options *options,
64
void do_route (const struct options *options,
65
	       struct route_list *route_list,
65
	       struct route_list *route_list,
66
	       struct route_ipv6_list *route_ipv6_list,
66
	       const struct tuntap *tt,
67
	       const struct tuntap *tt,
67
	       const struct plugin_list *plugins,
68
	       const struct plugin_list *plugins,
68
	       struct env_set *es);
69
	       struct env_set *es);
(-)openvpn-2.2.2_unpatched//misc.c (-1 / +3 lines)
Lines 1001-1007 Link Here
1001
	{
1001
	{
1002
	  const char *str = construct_name_value (name_tmp, val_tmp, &gc);
1002
	  const char *str = construct_name_value (name_tmp, val_tmp, &gc);
1003
	  env_set_add (es, str);
1003
	  env_set_add (es, str);
1004
	  /*msg (M_INFO, "SETENV_ES '%s'", str);*/
1004
#if DEBUG_VERBOSE_SETENV
1005
	  msg (M_INFO, "SETENV_ES '%s'", str);
1006
#endif
1005
	}
1007
	}
1006
      else
1008
      else
1007
	env_set_del (es, name_tmp);
1009
	env_set_del (es, name_tmp);
(-)openvpn-2.2.2_unpatched//mroute.c (-20 / +120 lines)
Lines 88-99 Link Here
88
    }
88
    }
89
}
89
}
90
90
91
static inline void
92
mroute_get_in6_addr (struct mroute_addr *ma, const struct in6_addr src, unsigned int mask)
93
{
94
  if (ma)
95
    {
96
      ma->type = MR_ADDR_IPV6 | mask;
97
      ma->netbits = 0;
98
      ma->len = 16;
99
      *(struct in6_addr *)ma->addr = src;
100
    }
101
}
102
91
static inline bool
103
static inline bool
92
mroute_is_mcast (const in_addr_t addr)
104
mroute_is_mcast (const in_addr_t addr)
93
{
105
{
94
  return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK));
106
  return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK));
95
}
107
}
96
108
109
/* RFC 4291, 2.7, "binary 11111111 at the start of an address identifies 
110
 *                 the address as being a multicast address"
111
 */
112
static inline bool
113
mroute_is_mcast_ipv6 (const struct in6_addr addr)
114
{
115
  return (addr.s6_addr[0] == 0xff);
116
}
117
97
#ifdef ENABLE_PF
118
#ifdef ENABLE_PF
98
119
99
static unsigned int
120
static unsigned int
Lines 157-169 Link Here
157
	    }
178
	    }
158
	  break;
179
	  break;
159
	case 6:
180
	case 6:
160
	  {
181
          if (BLEN (buf) >= (int) sizeof (struct openvpn_ipv6hdr))
161
            if( !ipv6warned ) {
182
            {
162
              msg (M_WARN, "IPv6 in tun mode is not supported in OpenVPN 2.2");
183
              const struct openvpn_ipv6hdr *ipv6 = (const struct openvpn_ipv6hdr *) BPTR (buf);
163
              ipv6warned = true;
184
#if 0                          /* very basic debug */
185
              struct gc_arena gc = gc_new ();
186
              msg( M_INFO, "IPv6 packet! src=%s, dst=%s",
187
                        print_in6_addr( ipv6->saddr, 0, &gc ),
188
                        print_in6_addr( ipv6->daddr, 0, &gc ));
189
              gc_free (&gc);
190
#endif
191
192
              mroute_get_in6_addr (src, ipv6->saddr, 0);
193
              mroute_get_in6_addr (dest, ipv6->daddr, 0);
194
195
              if (mroute_is_mcast_ipv6 (ipv6->daddr))
196
                ret |= MROUTE_EXTRACT_MCAST;
197
198
              ret |= MROUTE_EXTRACT_SUCCEEDED;
164
            }
199
            }
165
	    break;
200
          break;
166
	  }
201
       default:
202
           msg (M_WARN, "IP packet with unknown IP version=%d seen",
203
                        OPENVPN_IPH_GET_VER (*BPTR(buf)));
167
	}
204
	}
168
    }
205
    }
169
  return ret;
206
  return ret;
Lines 257-270 Link Here
257
 * Zero off the host bits in an address, leaving
294
 * Zero off the host bits in an address, leaving
258
 * only the network bits, using the netbits member of
295
 * only the network bits, using the netbits member of
259
 * struct mroute_addr as the controlling parameter.
296
 * struct mroute_addr as the controlling parameter.
297
 *
298
 * TODO: this is called for route-lookup for every yet-unhashed
299
 * destination address, so for lots of active net-iroutes, this
300
 * might benefit from some "zeroize 32 bit at a time" improvements
260
 */
301
 */
261
void
302
void
262
mroute_addr_mask_host_bits (struct mroute_addr *ma)
303
mroute_addr_mask_host_bits (struct mroute_addr *ma)
263
{
304
{
264
  in_addr_t addr = ntohl(*(in_addr_t*)ma->addr);
305
  in_addr_t addr = ntohl(*(in_addr_t*)ma->addr);
265
  ASSERT ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4);
306
  if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
266
  addr &= netbits_to_netmask (ma->netbits);
307
    {
267
  *(in_addr_t*)ma->addr = htonl (addr);
308
      addr &= netbits_to_netmask (ma->netbits);
309
      *(in_addr_t*)ma->addr = htonl (addr);
310
    }
311
  else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
312
    {
313
      int byte = ma->len-1;		/* rightmost byte in address */
314
      int bits_to_clear = 128 - ma->netbits;
315
316
      while( byte >= 0 && bits_to_clear > 0 )
317
        {
318
	  if ( bits_to_clear >= 8 )
319
	    { ma->addr[byte--] = 0; bits_to_clear -= 8; }
320
	  else
321
	    { ma->addr[byte--] &= (~0 << bits_to_clear); bits_to_clear = 0; }
322
        }
323
      ASSERT( bits_to_clear == 0 );
324
    }
325
  else
326
      ASSERT(0);
268
}
327
}
269
328
270
/*
329
/*
Lines 342-358 Link Here
342
	  }
401
	  }
343
	  break;
402
	  break;
344
	case MR_ADDR_IPV6:
403
	case MR_ADDR_IPV6:
345
	  buf_printf (&out, "IPV6"); 
404
	  {
346
	  break;
405
	    buf_printf (&out, "%s",
347
	default:
406
		  print_in6_addr( *(struct in6_addr*)&maddr.addr, 0, gc)); 
348
	  buf_printf (&out, "UNKNOWN"); 
407
	    if (maddr.type & MR_WITH_NETBITS)
349
	  break;
408
	      {
350
	}
409
		buf_printf (&out, "/%d", maddr.netbits);
351
      return BSTR (&out);
410
	      }
352
    }
411
	    }
353
  else
412
	    break;
354
    return "[NULL]";
413
	  default:
355
}
414
	    buf_printf (&out, "UNKNOWN"); 
415
	    break;
416
	  }
417
	return BSTR (&out);
418
      }
419
    else
420
      return "[NULL]";
421
  }
356
422
357
/*
423
/*
358
 * mroute_helper's main job is keeping track of
424
 * mroute_helper's main job is keeping track of
Lines 422-427 Link Here
422
	mroute_helper_regenerate (mh);
488
	mroute_helper_regenerate (mh);
423
    }
489
    }
424
}
490
}
491
492
/* this is a bit inelegant, we really should have a helper to that 
493
 * is only passed the netbits value, and not the whole struct iroute *
494
 * - thus one helper could do IPv4 and IPv6.  For the sake of "not change
495
 * code unrelated to IPv4" this is left for later cleanup, for now.
496
 */
497
void
498
mroute_helper_add_iroute6 (struct mroute_helper *mh, 
499
                           const struct iroute_ipv6 *ir6)
500
{
501
  if (ir6->netbits >= 0)
502
    {
503
      ASSERT (ir6->netbits < MR_HELPER_NET_LEN);
504
      ++mh->cache_generation;
505
      ++mh->net_len_refcount[ir6->netbits];
506
      if (mh->net_len_refcount[ir6->netbits] == 1)
507
	mroute_helper_regenerate (mh);
508
    }
509
}
510
511
void
512
mroute_helper_del_iroute6 (struct mroute_helper *mh, 
513
			   const struct iroute_ipv6 *ir6)
514
{
515
  if (ir6->netbits >= 0)
516
    {
517
      ASSERT (ir6->netbits < MR_HELPER_NET_LEN);
518
      ++mh->cache_generation;
519
      --mh->net_len_refcount[ir6->netbits];
520
      ASSERT (mh->net_len_refcount[ir6->netbits] >= 0);
521
      if (!mh->net_len_refcount[ir6->netbits])
522
	mroute_helper_regenerate (mh);
523
    }
524
}
425
525
426
void
526
void
427
mroute_helper_free (struct mroute_helper *mh)
527
mroute_helper_free (struct mroute_helper *mh)
(-)openvpn-2.2.2_unpatched//mroute.h (-1 / +3 lines)
Lines 85-91 Link Here
85
/*
85
/*
86
 * Number of bits in an address.  Should be raised for IPv6.
86
 * Number of bits in an address.  Should be raised for IPv6.
87
 */
87
 */
88
#define MR_HELPER_NET_LEN 32
88
#define MR_HELPER_NET_LEN 129
89
89
90
/*
90
/*
91
 * Used to help maintain CIDR routing table.
91
 * Used to help maintain CIDR routing table.
Lines 127-132 Link Here
127
void mroute_helper_free (struct mroute_helper *mh);
127
void mroute_helper_free (struct mroute_helper *mh);
128
void mroute_helper_add_iroute (struct mroute_helper *mh, const struct iroute *ir);
128
void mroute_helper_add_iroute (struct mroute_helper *mh, const struct iroute *ir);
129
void mroute_helper_del_iroute (struct mroute_helper *mh, const struct iroute *ir);
129
void mroute_helper_del_iroute (struct mroute_helper *mh, const struct iroute *ir);
130
void mroute_helper_add_iroute6 (struct mroute_helper *mh, const struct iroute_ipv6 *ir6);
131
void mroute_helper_del_iroute6 (struct mroute_helper *mh, const struct iroute_ipv6 *ir6);
130
132
131
/*
133
/*
132
 * Given a raw packet in buf, return the src and dest
134
 * Given a raw packet in buf, return the src and dest
(-)openvpn-2.2.2_unpatched//multi.c (-20 / +129 lines)
Lines 316-340 Link Here
316
   */
316
   */
317
  if (t->options.ifconfig_pool_defined)
317
  if (t->options.ifconfig_pool_defined)
318
    {
318
    {
319
      if (dev == DEV_TYPE_TAP)
319
      int pool_type = IFCONFIG_POOL_INDIV;
320
	{
320
321
	  m->ifconfig_pool = ifconfig_pool_init (IFCONFIG_POOL_INDIV,
321
      if ( dev == DEV_TYPE_TUN && t->options.topology == TOP_NET30 )
322
						 t->options.ifconfig_pool_start,
322
	pool_type = IFCONFIG_POOL_30NET;
323
						 t->options.ifconfig_pool_end,
323
324
						 t->options.duplicate_cn);
324
      m->ifconfig_pool = ifconfig_pool_init (pool_type,
325
	}
325
				 t->options.ifconfig_pool_start,
326
      else if (dev == DEV_TYPE_TUN)
326
				 t->options.ifconfig_pool_end,
327
	{
327
				 t->options.duplicate_cn,
328
	  m->ifconfig_pool = ifconfig_pool_init (
328
				 t->options.ifconfig_ipv6_pool_defined,
329
	    (t->options.topology == TOP_NET30) ? IFCONFIG_POOL_30NET : IFCONFIG_POOL_INDIV,
329
				 t->options.ifconfig_ipv6_pool_base,
330
	    t->options.ifconfig_pool_start,
330
				 t->options.ifconfig_ipv6_pool_netbits );
331
	    t->options.ifconfig_pool_end,
332
	    t->options.duplicate_cn);
333
	}
334
      else
335
	{
336
	  ASSERT (0);
337
	}
338
331
339
      /* reload pool data from file */
332
      /* reload pool data from file */
340
      if (t->c1.ifconfig_pool_persist)
333
      if (t->c1.ifconfig_pool_persist)
Lines 429-438 Link Here
429
		   struct multi_instance *mi)
422
		   struct multi_instance *mi)
430
{
423
{
431
  const struct iroute *ir;
424
  const struct iroute *ir;
425
  const struct iroute_ipv6 *ir6;
432
  if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
426
  if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
433
    {
427
    {
434
      for (ir = mi->context.options.iroutes; ir != NULL; ir = ir->next)
428
      for (ir = mi->context.options.iroutes; ir != NULL; ir = ir->next)
435
	mroute_helper_del_iroute (m->route_helper, ir);
429
	mroute_helper_del_iroute (m->route_helper, ir);
430
431
      for ( ir6 = mi->context.options.iroutes_ipv6; ir6 != NULL; ir6 = ir6->next )
432
	mroute_helper_del_iroute6 (m->route_helper, ir6);
436
    }
433
    }
437
}
434
}
438
435
Lines 1078-1083 Link Here
1078
  }
1075
  }
1079
}
1076
}
1080
1077
1078
static struct multi_instance *
1079
multi_learn_in6_addr  (struct multi_context *m,
1080
		       struct multi_instance *mi,
1081
		       struct in6_addr a6,
1082
		       int netbits, /* -1 if host route, otherwise # of network bits in address */
1083
		       bool primary)
1084
{
1085
  struct mroute_addr addr;
1086
1087
  addr.len = 16;
1088
  addr.type = MR_ADDR_IPV6;
1089
  addr.netbits = 0;
1090
  memcpy( &addr.addr, &a6, sizeof(a6) );
1091
1092
  if (netbits >= 0)
1093
    {
1094
      addr.type |= MR_WITH_NETBITS;
1095
      addr.netbits = (uint8_t) netbits;
1096
      mroute_addr_mask_host_bits( &addr );
1097
    }
1098
1099
  {
1100
    struct multi_instance *owner = multi_learn_addr (m, mi, &addr, 0);
1101
#ifdef MANAGEMENT_DEF_AUTH
1102
    if (management && owner)
1103
      management_learn_addr (management, &mi->context.c2.mda_context, &addr, primary);
1104
#endif
1105
    return owner;
1106
  }
1107
}
1108
1081
/*
1109
/*
1082
 * A new client has connected, add routes (server -> client)
1110
 * A new client has connected, add routes (server -> client)
1083
 * to internal routing table.
1111
 * to internal routing table.
Lines 1088-1093 Link Here
1088
{
1116
{
1089
  struct gc_arena gc = gc_new ();
1117
  struct gc_arena gc = gc_new ();
1090
  const struct iroute *ir;
1118
  const struct iroute *ir;
1119
  const struct iroute_ipv6 *ir6;
1091
  if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
1120
  if (TUNNEL_TYPE (mi->context.c1.tuntap) == DEV_TYPE_TUN)
1092
    {
1121
    {
1093
      mi->did_iroutes = true;
1122
      mi->did_iroutes = true;
Lines 1107-1112 Link Here
1107
      
1136
      
1108
	  multi_learn_in_addr_t (m, mi, ir->network, ir->netbits, false);
1137
	  multi_learn_in_addr_t (m, mi, ir->network, ir->netbits, false);
1109
	}
1138
	}
1139
      for ( ir6 = mi->context.options.iroutes_ipv6; ir6 != NULL; ir6 = ir6->next )
1140
	{
1141
	  if (ir6->netbits >= 0)
1142
	    msg (D_MULTI_LOW, "MULTI: internal route %s/%d -> %s",
1143
		 print_in6_addr (ir6->network, 0, &gc),
1144
		 ir6->netbits,
1145
		 multi_instance_string (mi, false, &gc));
1146
	  else
1147
	    msg (D_MULTI_LOW, "MULTI: internal route %s -> %s",
1148
		 print_in6_addr (ir6->network, 0, &gc),
1149
		 multi_instance_string (mi, false, &gc));
1150
1151
	  mroute_helper_add_iroute6 (m->route_helper, ir6);
1152
      
1153
	  multi_learn_in6_addr (m, mi, ir6->network, ir6->netbits, false);
1154
	}
1110
    }
1155
    }
1111
  gc_free (&gc);
1156
  gc_free (&gc);
1112
}
1157
}
Lines 1192-1212 Link Here
1192
      mi->context.c2.push_ifconfig_defined = true;
1237
      mi->context.c2.push_ifconfig_defined = true;
1193
      mi->context.c2.push_ifconfig_local = mi->context.options.push_ifconfig_local;
1238
      mi->context.c2.push_ifconfig_local = mi->context.options.push_ifconfig_local;
1194
      mi->context.c2.push_ifconfig_remote_netmask = mi->context.options.push_ifconfig_remote_netmask;
1239
      mi->context.c2.push_ifconfig_remote_netmask = mi->context.options.push_ifconfig_remote_netmask;
1240
1241
      /* the current implementation does not allow "static IPv4, pool IPv6",
1242
       * (see below) so issue a warning if that happens - don't break the
1243
       * session, though, as we don't even know if this client WANTS IPv6
1244
       */
1245
      if ( mi->context.c1.tuntap->ipv6 &&
1246
	   mi->context.options.ifconfig_ipv6_pool_defined &&
1247
	   ! mi->context.options.push_ifconfig_ipv6_defined )
1248
	{
1249
	  msg( M_INFO, "MULTI_sva: WARNING: if --ifconfig-push is used for IPv4, automatic IPv6 assignment from --ifconfig-ipv6-pool does not work.  Use --ifconfig-ipv6-push for IPv6 then." );
1250
	}
1195
    }
1251
    }
1196
  else if (m->ifconfig_pool && mi->vaddr_handle < 0) /* otherwise, choose a pool address */
1252
  else if (m->ifconfig_pool && mi->vaddr_handle < 0) /* otherwise, choose a pool address */
1197
    {
1253
    {
1198
      in_addr_t local=0, remote=0;
1254
      in_addr_t local=0, remote=0;
1255
      struct in6_addr remote_ipv6;
1199
      const char *cn = NULL;
1256
      const char *cn = NULL;
1200
1257
1201
      if (!mi->context.options.duplicate_cn)
1258
      if (!mi->context.options.duplicate_cn)
1202
	cn = tls_common_name (mi->context.c2.tls_multi, true);
1259
	cn = tls_common_name (mi->context.c2.tls_multi, true);
1203
1260
1204
      mi->vaddr_handle = ifconfig_pool_acquire (m->ifconfig_pool, &local, &remote, cn);
1261
      mi->vaddr_handle = ifconfig_pool_acquire (m->ifconfig_pool, &local, &remote, &remote_ipv6, cn);
1205
      if (mi->vaddr_handle >= 0)
1262
      if (mi->vaddr_handle >= 0)
1206
	{
1263
	{
1207
	  const int tunnel_type = TUNNEL_TYPE (mi->context.c1.tuntap);
1264
	  const int tunnel_type = TUNNEL_TYPE (mi->context.c1.tuntap);
1208
	  const int tunnel_topology = TUNNEL_TOPOLOGY (mi->context.c1.tuntap);
1265
	  const int tunnel_topology = TUNNEL_TOPOLOGY (mi->context.c1.tuntap);
1209
1266
1267
	  msg( M_INFO, "MULTI_sva: pool returned IPv4=%s, IPv6=%s", 
1268
		    print_in_addr_t( remote, 0, &gc ),
1269
		    print_in6_addr( remote_ipv6, 0, &gc ) );
1270
1210
	  /* set push_ifconfig_remote_netmask from pool ifconfig address(es) */
1271
	  /* set push_ifconfig_remote_netmask from pool ifconfig address(es) */
1211
	  mi->context.c2.push_ifconfig_local = remote;
1272
	  mi->context.c2.push_ifconfig_local = remote;
1212
	  if (tunnel_type == DEV_TYPE_TAP || (tunnel_type == DEV_TYPE_TUN && tunnel_topology == TOP_SUBNET))
1273
	  if (tunnel_type == DEV_TYPE_TAP || (tunnel_type == DEV_TYPE_TUN && tunnel_topology == TOP_SUBNET))
Lines 1228-1239 Link Here
1228
	  else
1289
	  else
1229
	    msg (D_MULTI_ERRORS, "MULTI: no --ifconfig-pool netmask parameter is available to push to %s",
1290
	    msg (D_MULTI_ERRORS, "MULTI: no --ifconfig-pool netmask parameter is available to push to %s",
1230
		 multi_instance_string (mi, false, &gc));
1291
		 multi_instance_string (mi, false, &gc));
1292
1293
	  if ( mi->context.options.ifconfig_ipv6_pool_defined )
1294
	    {
1295
	      mi->context.c2.push_ifconfig_ipv6_local = remote_ipv6;
1296
	      mi->context.c2.push_ifconfig_ipv6_remote = 
1297
		    mi->context.c1.tuntap->local_ipv6;
1298
	      mi->context.c2.push_ifconfig_ipv6_netbits = 
1299
		    mi->context.options.ifconfig_ipv6_pool_netbits;
1300
	      mi->context.c2.push_ifconfig_ipv6_defined = true;
1301
	    }
1231
	}
1302
	}
1232
      else
1303
      else
1233
	{
1304
	{
1234
	  msg (D_MULTI_ERRORS, "MULTI: no free --ifconfig-pool addresses are available");
1305
	  msg (D_MULTI_ERRORS, "MULTI: no free --ifconfig-pool addresses are available");
1235
	}
1306
	}
1236
    }
1307
    }
1308
1309
  /* IPv6 push_ifconfig is a bit problematic - since IPv6 shares the 
1310
   * pool handling with IPv4, the combination "static IPv4, dynamic IPv6"
1311
   * will fail (because no pool will be allocated in this case).
1312
   * OTOH, this doesn't make too much sense in reality - and the other
1313
   * way round ("dynamic IPv4, static IPv6") or "both static" makes sense
1314
   * -> and so it's implemented right now
1315
   */
1316
  if ( mi->context.c1.tuntap->ipv6 &&
1317
       mi->context.options.push_ifconfig_ipv6_defined )
1318
    {
1319
      mi->context.c2.push_ifconfig_ipv6_local = 
1320
	    mi->context.options.push_ifconfig_ipv6_local;
1321
      mi->context.c2.push_ifconfig_ipv6_remote = 
1322
	    mi->context.options.push_ifconfig_ipv6_remote;
1323
      mi->context.c2.push_ifconfig_ipv6_netbits = 
1324
	    mi->context.options.push_ifconfig_ipv6_netbits;
1325
      mi->context.c2.push_ifconfig_ipv6_defined = true;
1326
1327
      msg( M_INFO, "MULTI_sva: push_ifconfig_ipv6 %s/%d", 
1328
	    print_in6_addr( mi->context.c2.push_ifconfig_ipv6_local, 0, &gc ),
1329
	    mi->context.c2.push_ifconfig_ipv6_netbits );
1330
    }
1331
1237
  gc_free (&gc);
1332
  gc_free (&gc);
1238
}
1333
}
1239
1334
Lines 1272-1277 Link Here
1272
			    SA_SET_IF_NONZERO);
1367
			    SA_SET_IF_NONZERO);
1273
	}
1368
	}
1274
    }
1369
    }
1370
1371
    /* TODO: I'm not exactly sure what these environment variables are
1372
     *       used for, but if we have them for IPv4, we should also have
1373
     *       them for IPv6, no?
1374
     */
1275
}
1375
}
1276
1376
1277
/*
1377
/*
Lines 1661-1666 Link Here
1661
		       print_in_addr_t (mi->context.c2.push_ifconfig_local, 0, &gc));
1761
		       print_in_addr_t (mi->context.c2.push_ifconfig_local, 0, &gc));
1662
		}
1762
		}
1663
1763
1764
	      if (mi->context.c2.push_ifconfig_ipv6_defined)
1765
		{
1766
		  multi_learn_in6_addr (m, mi, mi->context.c2.push_ifconfig_ipv6_local, -1, true);
1767
		  /* TODO: find out where addresses are "unlearned"!! */
1768
		  msg (D_MULTI_LOW, "MULTI: primary virtual IPv6 for %s: %s",
1769
		       multi_instance_string (mi, false, &gc),
1770
		       print_in6_addr (mi->context.c2.push_ifconfig_ipv6_local, 0, &gc));
1771
		}
1772
1664
	      /* add routes locally, pointing to new client, if
1773
	      /* add routes locally, pointing to new client, if
1665
		 --iroute options have been specified */
1774
		 --iroute options have been specified */
1666
	      multi_add_iroutes (m, mi);
1775
	      multi_add_iroutes (m, mi);
(-)openvpn-2.2.2_unpatched//openvpn.8 (+53 lines)
Lines 794-799 Link Here
794
.B \-\-dev tunX.
794
.B \-\-dev tunX.
795
A warning will be displayed
795
A warning will be displayed
796
if no specific IPv6 TUN support for your OS has been compiled into OpenVPN.
796
if no specific IPv6 TUN support for your OS has been compiled into OpenVPN.
797
798
See below for further IPv6-related configuration options.
797
.\"*********************************************************
799
.\"*********************************************************
798
.TP
800
.TP
799
.B \-\-dev-node node
801
.B \-\-dev-node node
Lines 4949-4954 Link Here
4949
.B \-\-verb
4951
.B \-\-verb
4950
option can be used BEFORE this option to produce debugging information.
4952
option can be used BEFORE this option to produce debugging information.
4951
.\"*********************************************************
4953
.\"*********************************************************
4954
.SS IPv6 Related Options
4955
.\"*********************************************************
4956
The following options exist to support IPv6 tunneling in peer-to-peer
4957
and client-server mode.  As of now, this is just very basic
4958
documentation of the IPv6-related options. More documentation can be
4959
found on http://www.greenie.net/ipv6/openvpn.html.
4960
.TP
4961
.B --ifconfig-ipv6 ipv6addr/bits ipv6remote
4962
configure IPv6 address
4963
.B ipv6addr/bits
4964
on the ``tun'' device.  The second parameter is used as route target for
4965
.B --route-ipv6
4966
if no gateway is specified.
4967
.TP
4968
.B --route-ipv6 ipv6addr/bits [gateway] [metric]
4969
setup IPv6 routing in the system to send the specified IPv6 network
4970
into OpenVPN's ``tun'' device
4971
.TP
4972
.B --server-ipv6 ipv6addr/bits
4973
convenience-function to enable a number of IPv6 related options at
4974
once, namely
4975
.B --ifconfig-ipv6, --ifconfig-ipv6-pool, --tun-ipv6
4976
and
4977
.B --push tun-ipv6
4978
Is only accepted if ``--mode server'' or ``--server'' is set.
4979
.TP
4980
.B --ifconfig-ipv6-pool ipv6addr/bits
4981
Specify an IPv6 address pool for dynamic assignment to clients.  The
4982
pool starts at
4983
.B ipv6addr
4984
and increments by +1 for every new client (linear mode).  The
4985
.B /bits
4986
setting controls the size of the pool.
4987
.TP
4988
.B --ifconfig-ipv6-push ipv6addr/bits ipv6remote
4989
for ccd/ per-client static IPv6 interface configuration, see
4990
.B --client-config-dir
4991
and
4992
.B --ifconfig-push
4993
for more details.
4994
.TP
4995
.B --iroute-ipv6 ipv6addr/bits
4996
for ccd/ per-client static IPv6 route configuration, see
4997
.B --iroute
4998
for more details how to setup and use this, and how
4999
.B --iroute
5000
and
5001
.B --route
5002
interact.
5003
5004
.\"*********************************************************
4952
.SH SCRIPTING AND ENVIRONMENTAL VARIABLES
5005
.SH SCRIPTING AND ENVIRONMENTAL VARIABLES
4953
OpenVPN exports a series
5006
OpenVPN exports a series
4954
of environmental variables for use by user-defined scripts.
5007
of environmental variables for use by user-defined scripts.
(-)openvpn-2.2.2_unpatched//openvpn.h (+8 lines)
Lines 165-170 Link Here
165
  /* list of --route directives */
165
  /* list of --route directives */
166
  struct route_list *route_list;
166
  struct route_list *route_list;
167
167
168
  /* list of --route-ipv6 directives */
169
  struct route_ipv6_list *route_ipv6_list;
170
168
  /* --status file */
171
  /* --status file */
169
  struct status_output *status_output;
172
  struct status_output *status_output;
170
  bool status_output_owned;
173
  bool status_output_owned;
Lines 417-422 Link Here
417
  in_addr_t push_ifconfig_local;
420
  in_addr_t push_ifconfig_local;
418
  in_addr_t push_ifconfig_remote_netmask;
421
  in_addr_t push_ifconfig_remote_netmask;
419
422
423
  bool            push_ifconfig_ipv6_defined;
424
  struct in6_addr push_ifconfig_ipv6_local;
425
  int             push_ifconfig_ipv6_netbits;
426
  struct in6_addr push_ifconfig_ipv6_remote;
427
420
  /* client authentication state, CAS_SUCCEEDED must be 0 */
428
  /* client authentication state, CAS_SUCCEEDED must be 0 */
421
# define CAS_SUCCEEDED 0
429
# define CAS_SUCCEEDED 0
422
# define CAS_PENDING   1
430
# define CAS_PENDING   1
(-)openvpn-2.2.2_unpatched//options.c (+269 lines)
Lines 79-84 Link Here
79
#ifdef ENABLE_EUREPHIA
79
#ifdef ENABLE_EUREPHIA
80
  " [eurephia]"
80
  " [eurephia]"
81
#endif
81
#endif
82
  " [IPv6 payload 20110522-1 (2.2.0)]"
82
  " built on " __DATE__
83
  " built on " __DATE__
83
;
84
;
84
85
Lines 172-177 Link Here
172
  "                  addresses outside of the subnets used by either peer.\n"
173
  "                  addresses outside of the subnets used by either peer.\n"
173
  "                  TAP: configure device to use IP address l as a local\n"
174
  "                  TAP: configure device to use IP address l as a local\n"
174
  "                  endpoint and rn as a subnet mask.\n"
175
  "                  endpoint and rn as a subnet mask.\n"
176
  "--ifconfig-ipv6 l r : configure device to use IPv6 address l as local\n"
177
  "                      endpoint (as a /64) and r as remote endpoint\n"
175
  "--ifconfig-noexec : Don't actually execute ifconfig/netsh command, instead\n"
178
  "--ifconfig-noexec : Don't actually execute ifconfig/netsh command, instead\n"
176
  "                    pass --ifconfig parms by environment to scripts.\n"
179
  "                    pass --ifconfig parms by environment to scripts.\n"
177
  "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n"
180
  "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n"
Lines 182-187 Link Here
182
  "                  netmask default: 255.255.255.255\n"
185
  "                  netmask default: 255.255.255.255\n"
183
  "                  gateway default: taken from --route-gateway or --ifconfig\n"
186
  "                  gateway default: taken from --route-gateway or --ifconfig\n"
184
  "                  Specify default by leaving blank or setting to \"nil\".\n"
187
  "                  Specify default by leaving blank or setting to \"nil\".\n"
188
  "--route-ipv6 network/bits [gateway] [metric] :\n"
189
  "                  Add IPv6 route to routing table after connection\n"
190
  "                  is established.  Multiple routes can be specified.\n"
191
  "                  gateway default: taken from --route-ipv6-gateway or --ifconfig\n"
185
  "--max-routes n :  Specify the maximum number of routes that may be defined\n"
192
  "--max-routes n :  Specify the maximum number of routes that may be defined\n"
186
  "                  or pulled from a server.\n"
193
  "                  or pulled from a server.\n"
187
  "--route-gateway gw|'dhcp' : Specify a default gateway for use with --route.\n"
194
  "--route-gateway gw|'dhcp' : Specify a default gateway for use with --route.\n"
Lines 370-375 Link Here
370
  "\n"
377
  "\n"
371
  "Multi-Client Server options (when --mode server is used):\n"
378
  "Multi-Client Server options (when --mode server is used):\n"
372
  "--server network netmask : Helper option to easily configure server mode.\n"
379
  "--server network netmask : Helper option to easily configure server mode.\n"
380
  "--server-ipv6 network/bits : Configure IPv6 server mode.\n"
373
  "--server-bridge [IP netmask pool-start-IP pool-end-IP] : Helper option to\n"
381
  "--server-bridge [IP netmask pool-start-IP pool-end-IP] : Helper option to\n"
374
  "                    easily configure ethernet bridging server mode.\n"
382
  "                    easily configure ethernet bridging server mode.\n"
375
  "--push \"option\" : Push a config file option back to the peer for remote\n"
383
  "--push \"option\" : Push a config file option back to the peer for remote\n"
Lines 383-392 Link Here
383
  "--ifconfig-pool-persist file [seconds] : Persist/unpersist ifconfig-pool\n"
391
  "--ifconfig-pool-persist file [seconds] : Persist/unpersist ifconfig-pool\n"
384
  "                  data to file, at seconds intervals (default=600).\n"
392
  "                  data to file, at seconds intervals (default=600).\n"
385
  "                  If seconds=0, file will be treated as read-only.\n"
393
  "                  If seconds=0, file will be treated as read-only.\n"
394
  "--ifconfig-ipv6-pool base-IP/bits : set aside an IPv6 network block\n"
395
  "                  to be dynamically allocated to connecting clients.\n"
386
  "--ifconfig-push local remote-netmask : Push an ifconfig option to remote,\n"
396
  "--ifconfig-push local remote-netmask : Push an ifconfig option to remote,\n"
387
  "                  overrides --ifconfig-pool dynamic allocation.\n"
397
  "                  overrides --ifconfig-pool dynamic allocation.\n"
388
  "                  Only valid in a client-specific config file.\n"
398
  "                  Only valid in a client-specific config file.\n"
399
  "--ifconfig-ipv6-push local/bits remote : Push an ifconfig-ipv6 option to\n"
400
  "                  remote, overrides --ifconfig-ipv6-pool allocation.\n"
401
  "                  Only valid in a client-specific config file.\n"
389
  "--iroute network [netmask] : Route subnet to client.\n"
402
  "--iroute network [netmask] : Route subnet to client.\n"
403
  "--iroute-ipv6 network/bits : Route IPv6 subnet to client.\n"
390
  "                  Sets up internal routes only.\n"
404
  "                  Sets up internal routes only.\n"
391
  "                  Only valid in a client-specific config file.\n"
405
  "                  Only valid in a client-specific config file.\n"
392
  "--disable       : Client is disabled.\n"
406
  "--disable       : Client is disabled.\n"
Lines 871-876 Link Here
871
  return ret;
885
  return ret;
872
}
886
}
873
887
888
/* helper: parse a text string containing an IPv6 address + netbits
889
 * in "standard format" (2001:dba::/32)
890
 * "/nn" is optional, default to /64 if missing
891
 *
892
 * return true if parsing succeeded, modify *network and *netbits
893
 * return address part without "/nn" in *printable_ipv6 (if != NULL)
894
 */
895
bool
896
get_ipv6_addr( const char * prefix_str, struct in6_addr *network,
897
	       unsigned int * netbits, char ** printable_ipv6, int msglevel )
898
{
899
    int rc;
900
    char * sep, * endp;
901
    int bits;
902
    struct in6_addr t_network;
903
904
    sep = strchr( prefix_str, '/' );
905
    if ( sep == NULL )
906
      {
907
 	bits = 64;
908
      }
909
    else
910
      {
911
	bits = strtol( sep+1, &endp, 10 );
912
	if ( *endp != '\0' || bits < 0 || bits > 128 )
913
	  {
914
	    msg (msglevel, "IPv6 prefix '%s': invalid '/bits' spec", prefix_str);
915
	    return false;
916
	  }
917
      }
918
919
    /* temporary replace '/' in caller-provided string with '\0', otherwise
920
     * inet_pton() will refuse prefix string
921
     * (alternative would be to strncpy() the prefix to temporary buffer)
922
     */
923
924
    if ( sep != NULL ) *sep = '\0';
925
926
    rc = inet_pton( AF_INET6, prefix_str, &t_network );
927
928
    if ( rc == 1 && printable_ipv6 != NULL )
929
      {
930
	*printable_ipv6 = string_alloc( prefix_str, NULL );
931
      }
932
933
    if ( sep != NULL ) *sep = '/';
934
935
    if ( rc != 1 )
936
      {
937
	msg (msglevel, "IPv6 prefix '%s': invalid IPv6 address", prefix_str);
938
	return false;
939
      }
940
941
    if ( netbits != NULL )
942
      {
943
	*netbits = bits;
944
      }
945
    if ( network != NULL )
946
      {
947
	*network = t_network;
948
      }
949
    return true;		/* parsing OK, values set */
950
}
951
952
static bool ipv6_addr_safe_hexplusbits( const char * ipv6_prefix_spec )
953
{
954
    struct in6_addr t_addr;
955
    unsigned int t_bits;
956
957
    return get_ipv6_addr( ipv6_prefix_spec, &t_addr, &t_bits, NULL, M_WARN );
958
}
959
874
static char *
960
static char *
875
string_substitute (const char *src, int from, int to, struct gc_arena *gc)
961
string_substitute (const char *src, int from, int to, struct gc_arena *gc)
876
{
962
{
Lines 989-994 Link Here
989
#if P2MP_SERVER
1075
#if P2MP_SERVER
990
  msg (D_SHOW_PARMS, "  server_network = %s", print_in_addr_t (o->server_network, 0, &gc));
1076
  msg (D_SHOW_PARMS, "  server_network = %s", print_in_addr_t (o->server_network, 0, &gc));
991
  msg (D_SHOW_PARMS, "  server_netmask = %s", print_in_addr_t (o->server_netmask, 0, &gc));
1077
  msg (D_SHOW_PARMS, "  server_netmask = %s", print_in_addr_t (o->server_netmask, 0, &gc));
1078
  msg (D_SHOW_PARMS, "  server_network_ipv6 = %s", print_in6_addr (o->server_network_ipv6, 0, &gc) );
1079
  SHOW_INT (server_netbits_ipv6);
992
  msg (D_SHOW_PARMS, "  server_bridge_ip = %s", print_in_addr_t (o->server_bridge_ip, 0, &gc));
1080
  msg (D_SHOW_PARMS, "  server_bridge_ip = %s", print_in_addr_t (o->server_bridge_ip, 0, &gc));
993
  msg (D_SHOW_PARMS, "  server_bridge_netmask = %s", print_in_addr_t (o->server_bridge_netmask, 0, &gc));
1081
  msg (D_SHOW_PARMS, "  server_bridge_netmask = %s", print_in_addr_t (o->server_bridge_netmask, 0, &gc));
994
  msg (D_SHOW_PARMS, "  server_bridge_pool_start = %s", print_in_addr_t (o->server_bridge_pool_start, 0, &gc));
1082
  msg (D_SHOW_PARMS, "  server_bridge_pool_start = %s", print_in_addr_t (o->server_bridge_pool_start, 0, &gc));
Lines 1009-1014 Link Here
1009
  msg (D_SHOW_PARMS, "  ifconfig_pool_netmask = %s", print_in_addr_t (o->ifconfig_pool_netmask, 0, &gc));
1097
  msg (D_SHOW_PARMS, "  ifconfig_pool_netmask = %s", print_in_addr_t (o->ifconfig_pool_netmask, 0, &gc));
1010
  SHOW_STR (ifconfig_pool_persist_filename);
1098
  SHOW_STR (ifconfig_pool_persist_filename);
1011
  SHOW_INT (ifconfig_pool_persist_refresh_freq);
1099
  SHOW_INT (ifconfig_pool_persist_refresh_freq);
1100
  SHOW_BOOL (ifconfig_ipv6_pool_defined);
1101
  msg (D_SHOW_PARMS, "  ifconfig_ipv6_pool_base = %s", print_in6_addr (o->ifconfig_ipv6_pool_base, 0, &gc));
1102
  SHOW_INT (ifconfig_ipv6_pool_netbits);
1012
  SHOW_INT (n_bcast_buf);
1103
  SHOW_INT (n_bcast_buf);
1013
  SHOW_INT (tcp_queue_limit);
1104
  SHOW_INT (tcp_queue_limit);
1014
  SHOW_INT (real_hash_size);
1105
  SHOW_INT (real_hash_size);
Lines 1022-1027 Link Here
1022
  SHOW_BOOL (push_ifconfig_defined);
1113
  SHOW_BOOL (push_ifconfig_defined);
1023
  msg (D_SHOW_PARMS, "  push_ifconfig_local = %s", print_in_addr_t (o->push_ifconfig_local, 0, &gc));
1114
  msg (D_SHOW_PARMS, "  push_ifconfig_local = %s", print_in_addr_t (o->push_ifconfig_local, 0, &gc));
1024
  msg (D_SHOW_PARMS, "  push_ifconfig_remote_netmask = %s", print_in_addr_t (o->push_ifconfig_remote_netmask, 0, &gc));
1115
  msg (D_SHOW_PARMS, "  push_ifconfig_remote_netmask = %s", print_in_addr_t (o->push_ifconfig_remote_netmask, 0, &gc));
1116
  SHOW_BOOL (push_ifconfig_ipv6_defined);
1117
  msg (D_SHOW_PARMS, "  push_ifconfig_ipv6_local = %s/%d", print_in6_addr (o->push_ifconfig_ipv6_local, 0, &gc), o->push_ifconfig_ipv6_netbits );
1118
  msg (D_SHOW_PARMS, "  push_ifconfig_ipv6_remote = %s", print_in6_addr (o->push_ifconfig_ipv6_remote, 0, &gc));
1025
  SHOW_BOOL (enable_c2c);
1119
  SHOW_BOOL (enable_c2c);
1026
  SHOW_BOOL (duplicate_cn);
1120
  SHOW_BOOL (duplicate_cn);
1027
  SHOW_INT (cf_max);
1121
  SHOW_INT (cf_max);
Lines 1076-1081 Link Here
1076
  o->iroutes = ir;
1170
  o->iroutes = ir;
1077
}
1171
}
1078
1172
1173
static void
1174
option_iroute_ipv6 (struct options *o,
1175
	       const char *prefix_str,
1176
	       int msglevel)
1177
{
1178
  struct iroute_ipv6 *ir;
1179
1180
  ALLOC_OBJ_GC (ir, struct iroute_ipv6, &o->gc);
1181
1182
  if ( get_ipv6_addr (prefix_str, &ir->network, &ir->netbits, NULL, msglevel ) < 0 )
1183
    {
1184
      msg (msglevel, "in --iroute-ipv6 %s: Bad IPv6 prefix specification",
1185
	   prefix_str);
1186
      return;
1187
    }
1188
1189
  ir->next = o->iroutes_ipv6;
1190
  o->iroutes_ipv6 = ir;
1191
}
1079
#endif /* P2MP_SERVER */
1192
#endif /* P2MP_SERVER */
1080
#endif /* P2MP */
1193
#endif /* P2MP */
1081
1194
Lines 1113-1118 Link Here
1113
    options->routes = new_route_option_list (options->max_routes, &options->gc);
1226
    options->routes = new_route_option_list (options->max_routes, &options->gc);
1114
}
1227
}
1115
1228
1229
void
1230
rol6_check_alloc (struct options *options)
1231
{
1232
  if (!options->routes_ipv6)
1233
    options->routes_ipv6 = new_route_ipv6_option_list (options->max_routes, &options->gc);
1234
}
1235
1116
#ifdef ENABLE_DEBUG
1236
#ifdef ENABLE_DEBUG
1117
static void
1237
static void
1118
show_connection_entry (const struct connection_entry *o)
1238
show_connection_entry (const struct connection_entry *o)
Lines 1203-1208 Link Here
1203
  SHOW_STR (ifconfig_remote_netmask);
1323
  SHOW_STR (ifconfig_remote_netmask);
1204
  SHOW_BOOL (ifconfig_noexec);
1324
  SHOW_BOOL (ifconfig_noexec);
1205
  SHOW_BOOL (ifconfig_nowarn);
1325
  SHOW_BOOL (ifconfig_nowarn);
1326
  SHOW_STR (ifconfig_ipv6_local);
1327
  SHOW_INT (ifconfig_ipv6_netbits);
1328
  SHOW_STR (ifconfig_ipv6_remote);
1206
1329
1207
#ifdef HAVE_GETTIMEOFDAY
1330
#ifdef HAVE_GETTIMEOFDAY
1208
  SHOW_INT (shaper);
1331
  SHOW_INT (shaper);
Lines 1863-1870 Link Here
1863
      if (options->connection_list)
1986
      if (options->connection_list)
1864
	msg (M_USAGE, "<connection> cannot be used with --mode server");
1987
	msg (M_USAGE, "<connection> cannot be used with --mode server");
1865
#endif
1988
#endif
1989
#if 0
1866
      if (options->tun_ipv6)
1990
      if (options->tun_ipv6)
1867
	msg (M_USAGE, "--tun-ipv6 cannot be used with --mode server");
1991
	msg (M_USAGE, "--tun-ipv6 cannot be used with --mode server");
1992
#endif
1868
      if (options->shaper)
1993
      if (options->shaper)
1869
	msg (M_USAGE, "--shaper cannot be used with --mode server");
1994
	msg (M_USAGE, "--shaper cannot be used with --mode server");
1870
      if (options->inetd)
1995
      if (options->inetd)
Lines 1889-1894 Link Here
1889
	msg (M_USAGE, "--up-delay cannot be used with --mode server");
2014
	msg (M_USAGE, "--up-delay cannot be used with --mode server");
1890
      if (!options->ifconfig_pool_defined && options->ifconfig_pool_persist_filename)
2015
      if (!options->ifconfig_pool_defined && options->ifconfig_pool_persist_filename)
1891
	msg (M_USAGE, "--ifconfig-pool-persist must be used with --ifconfig-pool");
2016
	msg (M_USAGE, "--ifconfig-pool-persist must be used with --ifconfig-pool");
2017
      if (options->ifconfig_ipv6_pool_defined && !options->ifconfig_ipv6_local )
2018
	msg (M_USAGE, "--ifconfig-ipv6-pool needs --ifconfig-ipv6");
2019
      if (options->ifconfig_ipv6_local && !options->tun_ipv6 )
2020
	msg (M_INFO, "Warning: --ifconfig-ipv6 without --tun-ipv6 will not do IPv6");
2021
1892
      if (options->auth_user_pass_file)
2022
      if (options->auth_user_pass_file)
1893
	msg (M_USAGE, "--auth-user-pass cannot be used with --mode server (it should be used on the client side only)");
2023
	msg (M_USAGE, "--auth-user-pass cannot be used with --mode server (it should be used on the client side only)");
1894
      if (options->ccd_exclusive && !options->client_config_dir)
2024
      if (options->ccd_exclusive && !options->client_config_dir)
Lines 1920-1925 Link Here
1920
       */
2050
       */
1921
      if (options->ifconfig_pool_defined || options->ifconfig_pool_persist_filename)
2051
      if (options->ifconfig_pool_defined || options->ifconfig_pool_persist_filename)
1922
	msg (M_USAGE, "--ifconfig-pool/--ifconfig-pool-persist requires --mode server");
2052
	msg (M_USAGE, "--ifconfig-pool/--ifconfig-pool-persist requires --mode server");
2053
      if (options->ifconfig_ipv6_pool_defined)
2054
	msg (M_USAGE, "--ifconfig-ipv6-pool requires --mode server");
1923
      if (options->real_hash_size != defaults.real_hash_size
2055
      if (options->real_hash_size != defaults.real_hash_size
1924
	  || options->virtual_hash_size != defaults.virtual_hash_size)
2056
	  || options->virtual_hash_size != defaults.virtual_hash_size)
1925
	msg (M_USAGE, "--hash-size requires --mode server");
2057
	msg (M_USAGE, "--hash-size requires --mode server");
Lines 2461-2466 Link Here
2461
		     o->topology,
2593
		     o->topology,
2462
		     o->ifconfig_local,
2594
		     o->ifconfig_local,
2463
		     o->ifconfig_remote_netmask,
2595
		     o->ifconfig_remote_netmask,
2596
		     o->ifconfig_ipv6_local,
2597
		     o->ifconfig_ipv6_remote,
2464
		     (in_addr_t)0,
2598
		     (in_addr_t)0,
2465
		     (in_addr_t)0,
2599
		     (in_addr_t)0,
2466
		     false,
2600
		     false,
Lines 3786-3791 Link Here
3786
	  goto err;
3920
	  goto err;
3787
	}
3921
	}
3788
    }
3922
    }
3923
  else if (streq (p[0], "ifconfig-ipv6") && p[1] && p[2] )
3924
    {
3925
      unsigned int netbits;
3926
      char * ipv6_local;
3927
	
3928
      VERIFY_PERMISSION (OPT_P_UP);
3929
      if ( get_ipv6_addr( p[1], NULL, &netbits, &ipv6_local, msglevel ) &&
3930
           ipv6_addr_safe( p[2] ) )
3931
        {
3932
	  if ( netbits < 64 || netbits > 124 )
3933
	    {
3934
	      msg( msglevel, "ifconfig-ipv6: /netbits must be between 64 and 124, not '/%d'", netbits );
3935
	      goto err;
3936
	    }
3937
	  options->ifconfig_ipv6_local = ipv6_local;
3938
	  options->ifconfig_ipv6_netbits = netbits;
3939
	  options->ifconfig_ipv6_remote = p[2];
3940
        }
3941
      else
3942
	{
3943
	  msg (msglevel, "ifconfig-ipv6 parms '%s' and '%s' must be valid addresses", p[1], p[2]);
3944
	  goto err;
3945
	}
3946
    }
3789
  else if (streq (p[0], "ifconfig-noexec"))
3947
  else if (streq (p[0], "ifconfig-noexec"))
3790
    {
3948
    {
3791
      VERIFY_PERMISSION (OPT_P_UP);
3949
      VERIFY_PERMISSION (OPT_P_UP);
Lines 4586-4591 Link Here
4586
	}
4744
	}
4587
      add_route_to_option_list (options->routes, p[1], p[2], p[3], p[4]);
4745
      add_route_to_option_list (options->routes, p[1], p[2], p[3], p[4]);
4588
    }
4746
    }
4747
  else if (streq (p[0], "route-ipv6") && p[1])
4748
    {
4749
      VERIFY_PERMISSION (OPT_P_ROUTE);
4750
      rol6_check_alloc (options);
4751
      if (pull_mode)
4752
	{
4753
	  if (!ipv6_addr_safe_hexplusbits (p[1]))
4754
	    {
4755
	      msg (msglevel, "route-ipv6 parameter network/IP '%s' must be a valid address", p[1]);
4756
	      goto err;
4757
	    }
4758
	  if (p[2] && !ipv6_addr_safe (p[2]))
4759
	    {
4760
	      msg (msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]);
4761
	      goto err;
4762
	    }
4763
	  /* p[3] is metric, if present */
4764
	}
4765
      add_route_ipv6_to_option_list (options->routes_ipv6, p[1], p[2], p[3]);
4766
    }
4589
  else if (streq (p[0], "max-routes") && p[1])
4767
  else if (streq (p[0], "max-routes") && p[1])
4590
    {
4768
    {
4591
      int max_routes;
4769
      int max_routes;
Lines 4797-4802 Link Here
4797
	    }
4975
	    }
4798
	}
4976
	}
4799
    }
4977
    }
4978
  else if (streq (p[0], "server-ipv6") && p[1] )
4979
    {
4980
      const int lev = M_WARN;
4981
      struct in6_addr network;
4982
      unsigned int netbits = 0;
4983
4984
      VERIFY_PERMISSION (OPT_P_GENERAL);
4985
      if ( ! get_ipv6_addr (p[1], &network, &netbits, NULL, lev) )
4986
	{
4987
	  msg (msglevel, "error parsing --server-ipv6 parameter");
4988
	  goto err;
4989
	}
4990
      if ( netbits != 64 )
4991
	{
4992
	  msg( msglevel, "--server-ipv6 settings: only /64 supported right now (not /%d)", netbits );
4993
	  goto err;
4994
	}
4995
      options->server_ipv6_defined = true;
4996
      options->server_network_ipv6 = network;
4997
      options->server_netbits_ipv6 = netbits;
4998
4999
      if (p[2])		/* no "nopool" options or similar for IPv6 */
5000
	{
5001
	  msg (msglevel, "error parsing --server-ipv6: %s is not a recognized flag", p[3]);
5002
	  goto err;
5003
	}
5004
    }
4800
  else if (streq (p[0], "server-bridge") && p[1] && p[2] && p[3] && p[4])
5005
  else if (streq (p[0], "server-bridge") && p[1] && p[2] && p[3] && p[4])
4801
    {
5006
    {
4802
      const int lev = M_WARN;
5007
      const int lev = M_WARN;
Lines 4881-4886 Link Here
4881
      VERIFY_PERMISSION (OPT_P_GENERAL);
5086
      VERIFY_PERMISSION (OPT_P_GENERAL);
4882
      options->topology = TOP_P2P;
5087
      options->topology = TOP_P2P;
4883
    }
5088
    }
5089
  else if (streq (p[0], "ifconfig-ipv6-pool") && p[1] )
5090
    {
5091
      const int lev = M_WARN;
5092
      struct in6_addr network;
5093
      unsigned int netbits = 0;
5094
5095
      VERIFY_PERMISSION (OPT_P_GENERAL);
5096
      if ( ! get_ipv6_addr (p[1], &network, &netbits, NULL, lev ) )
5097
	{
5098
	  msg (msglevel, "error parsing --ifconfig-ipv6-pool parameters");
5099
	  goto err;
5100
	}
5101
      if ( netbits != 64 )
5102
	{
5103
	  msg( msglevel, "--ifconfig-ipv6-pool settings: only /64 supported right now (not /%d)", netbits );
5104
	  goto err;
5105
	}
5106
5107
      options->ifconfig_ipv6_pool_defined = true;
5108
      options->ifconfig_ipv6_pool_base = network;
5109
      options->ifconfig_ipv6_pool_netbits = netbits;
5110
    }
4884
  else if (streq (p[0], "hash-size") && p[1] && p[2])
5111
  else if (streq (p[0], "hash-size") && p[1] && p[2])
4885
    {
5112
    {
4886
      int real, virtual;
5113
      int real, virtual;
Lines 5076-5081 Link Here
5076
	}
5303
	}
5077
      option_iroute (options, p[1], netmask, msglevel);
5304
      option_iroute (options, p[1], netmask, msglevel);
5078
    }
5305
    }
5306
  else if (streq (p[0], "iroute-ipv6") && p[1])
5307
    {
5308
      VERIFY_PERMISSION (OPT_P_INSTANCE);
5309
      option_iroute_ipv6 (options, p[1], msglevel);
5310
    }
5079
  else if (streq (p[0], "ifconfig-push") && p[1] && p[2])
5311
  else if (streq (p[0], "ifconfig-push") && p[1] && p[2])
5080
    {
5312
    {
5081
      in_addr_t local, remote_netmask;
5313
      in_addr_t local, remote_netmask;
Lines 5114-5119 Link Here
5114
	  goto err;
5346
	  goto err;
5115
	}
5347
	}
5116
    }
5348
    }
5349
  else if (streq (p[0], "ifconfig-ipv6-push") && p[1] )
5350
    {
5351
      struct in6_addr local, remote;
5352
      unsigned int netbits;
5353
5354
      VERIFY_PERMISSION (OPT_P_INSTANCE);
5355
5356
      if ( ! get_ipv6_addr( p[1], &local, &netbits, NULL, msglevel ) )
5357
	{
5358
	  msg (msglevel, "cannot parse --ifconfig-ipv6-push addresses");
5359
	  goto err;
5360
	}
5361
5362
      if ( p[2] )
5363
	{
5364
	  if ( !get_ipv6_addr( p[2], &remote, NULL, NULL, msglevel ) )
5365
	    {
5366
	      msg( msglevel, "cannot parse --ifconfig-ipv6-push addresses");
5367
	      goto err;
5368
	    }
5369
	}
5370
      else
5371
	{
5372
	  if ( ! options->ifconfig_ipv6_local ||
5373
	       ! get_ipv6_addr( options->ifconfig_ipv6_local, &remote, 
5374
				NULL, NULL, msglevel ) )
5375
	    {
5376
	      msg( msglevel, "second argument to --ifconfig-ipv6-push missing and no global --ifconfig-ipv6 address set");
5377
	      goto err;
5378
	    }
5379
	}
5380
5381
      options->push_ifconfig_ipv6_defined = true;
5382
      options->push_ifconfig_ipv6_local = local;
5383
      options->push_ifconfig_ipv6_netbits = netbits;
5384
      options->push_ifconfig_ipv6_remote = remote;
5385
    }
5117
  else if (streq (p[0], "disable"))
5386
  else if (streq (p[0], "disable"))
5118
    {
5387
    {
5119
      VERIFY_PERMISSION (OPT_P_INSTANCE);
5388
      VERIFY_PERMISSION (OPT_P_INSTANCE);
(-)openvpn-2.2.2_unpatched//options.h (+21 lines)
Lines 205-210 Link Here
205
  int topology; /* one of the TOP_x values from proto.h */
205
  int topology; /* one of the TOP_x values from proto.h */
206
  const char *ifconfig_local;
206
  const char *ifconfig_local;
207
  const char *ifconfig_remote_netmask;
207
  const char *ifconfig_remote_netmask;
208
  const char *ifconfig_ipv6_local;
209
  int         ifconfig_ipv6_netbits;
210
  const char *ifconfig_ipv6_remote;
208
  bool ifconfig_noexec;
211
  bool ifconfig_noexec;
209
  bool ifconfig_nowarn;
212
  bool ifconfig_nowarn;
210
#ifdef HAVE_GETTIMEOFDAY
213
#ifdef HAVE_GETTIMEOFDAY
Lines 326-331 Link Here
326
  bool route_delay_defined;
329
  bool route_delay_defined;
327
  int max_routes;
330
  int max_routes;
328
  struct route_option_list *routes;
331
  struct route_option_list *routes;
332
  struct route_ipv6_option_list *routes_ipv6;			/* IPv6 */
329
  bool route_nopull;
333
  bool route_nopull;
330
  bool route_gateway_via_dhcp;
334
  bool route_gateway_via_dhcp;
331
  bool allow_pull_fqdn; /* as a client, allow server to push a FQDN for certain parameters */
335
  bool allow_pull_fqdn; /* as a client, allow server to push a FQDN for certain parameters */
Lines 363-368 Link Here
363
  bool server_defined;
367
  bool server_defined;
364
  in_addr_t server_network;
368
  in_addr_t server_network;
365
  in_addr_t server_netmask;
369
  in_addr_t server_netmask;
370
  bool server_ipv6_defined;				/* IPv6 */
371
  struct in6_addr server_network_ipv6;			/* IPv6 */
372
  unsigned int    server_netbits_ipv6;			/* IPv6 */
366
373
367
# define SF_NOPOOL (1<<0)
374
# define SF_NOPOOL (1<<0)
368
# define SF_TCP_NODELAY_HELPER (1<<1)
375
# define SF_TCP_NODELAY_HELPER (1<<1)
Lines 384-389 Link Here
384
  in_addr_t ifconfig_pool_netmask;
391
  in_addr_t ifconfig_pool_netmask;
385
  const char *ifconfig_pool_persist_filename;
392
  const char *ifconfig_pool_persist_filename;
386
  int ifconfig_pool_persist_refresh_freq;
393
  int ifconfig_pool_persist_refresh_freq;
394
395
  bool   ifconfig_ipv6_pool_defined;                   /* IPv6 */
396
  struct in6_addr ifconfig_ipv6_pool_base;             /* IPv6 */
397
  int    ifconfig_ipv6_pool_netbits;                   /* IPv6 */
398
387
  int real_hash_size;
399
  int real_hash_size;
388
  int virtual_hash_size;
400
  int virtual_hash_size;
389
  const char *client_connect_script;
401
  const char *client_connect_script;
Lines 395-406 Link Here
395
  int n_bcast_buf;
407
  int n_bcast_buf;
396
  int tcp_queue_limit;
408
  int tcp_queue_limit;
397
  struct iroute *iroutes;
409
  struct iroute *iroutes;
410
  struct iroute_ipv6 *iroutes_ipv6;                    /* IPv6 */
398
  bool push_ifconfig_defined;
411
  bool push_ifconfig_defined;
399
  in_addr_t push_ifconfig_local;
412
  in_addr_t push_ifconfig_local;
400
  in_addr_t push_ifconfig_remote_netmask;
413
  in_addr_t push_ifconfig_remote_netmask;
401
  bool push_ifconfig_constraint_defined;
414
  bool push_ifconfig_constraint_defined;
402
  in_addr_t push_ifconfig_constraint_network;
415
  in_addr_t push_ifconfig_constraint_network;
403
  in_addr_t push_ifconfig_constraint_netmask;
416
  in_addr_t push_ifconfig_constraint_netmask;
417
  bool            push_ifconfig_ipv6_defined;          /* IPv6 */
418
  struct in6_addr push_ifconfig_ipv6_local;            /* IPv6 */
419
  int            push_ifconfig_ipv6_netbits;           /* IPv6 */
420
  struct in6_addr push_ifconfig_ipv6_remote;           /* IPv6 */
404
  bool enable_c2c;
421
  bool enable_c2c;
405
  bool duplicate_cn;
422
  bool duplicate_cn;
406
  int cf_max;
423
  int cf_max;
Lines 723-728 Link Here
723
			    unsigned int *option_types_found,
740
			    unsigned int *option_types_found,
724
			    struct env_set *es);
741
			    struct env_set *es);
725
742
743
bool get_ipv6_addr( const char * prefix_str, struct in6_addr *network,
744
		    unsigned int * netbits, char ** printable_ipv6, 
745
		    int msglevel );
746
726
/*
747
/*
727
 * inline functions
748
 * inline functions
728
 */
749
 */
(-)openvpn-2.2.2_unpatched//pool.c (-9 / +66 lines)
Lines 132-138 Link Here
132
}
132
}
133
133
134
struct ifconfig_pool *
134
struct ifconfig_pool *
135
ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn)
135
ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, 
136
		    const bool duplicate_cn,
137
		    const bool ipv6_pool, const struct in6_addr ipv6_base, 
138
		    const int ipv6_netbits )
136
{
139
{
137
  struct gc_arena gc = gc_new ();
140
  struct gc_arena gc = gc_new ();
138
  struct ifconfig_pool *pool = NULL;
141
  struct ifconfig_pool *pool = NULL;
Lines 157-167 Link Here
157
      ASSERT (0);
160
      ASSERT (0);
158
    }
161
    }
159
162
163
  /* IPv6 pools are always "INDIV" type */
164
  pool->ipv6 = ipv6_pool;
165
166
  if ( pool->ipv6 )
167
    {
168
      pool->base_ipv6 = ipv6_base;
169
      pool->size_ipv6 = ipv6_netbits>96? ( 1<<(128-ipv6_netbits) ) 
170
				       : IFCONFIG_POOL_MAX;
171
172
      msg( D_IFCONFIG_POOL, "IFCONFIG POOL IPv6: (IPv4) size=%d, size_ipv6=%d, netbits=%d, base_ipv6=%s",
173
			    pool->size, pool->size_ipv6, ipv6_netbits,
174
			    print_in6_addr( pool->base_ipv6, 0, &gc ));
175
176
      /* the current code is very simple and assumes that the IPv6
177
       * pool is at least as big as the IPv4 pool, and we don't need
178
       * to do separate math etc. for IPv6
179
       */
180
      ASSERT( pool->size < pool->size_ipv6 );
181
    }
182
160
  ALLOC_ARRAY_CLEAR (pool->list, struct ifconfig_pool_entry, pool->size);
183
  ALLOC_ARRAY_CLEAR (pool->list, struct ifconfig_pool_entry, pool->size);
161
184
162
  msg (D_IFCONFIG_POOL, "IFCONFIG POOL: base=%s size=%d",
185
  msg (D_IFCONFIG_POOL, "IFCONFIG POOL: base=%s size=%d, ipv6=%d",
163
       print_in_addr_t (pool->base, 0, &gc),
186
       print_in_addr_t (pool->base, 0, &gc),
164
       pool->size);
187
       pool->size, pool->ipv6 );
165
188
166
  gc_free (&gc);
189
  gc_free (&gc);
167
  return pool;
190
  return pool;
Lines 181-187 Link Here
181
}
204
}
182
205
183
ifconfig_pool_handle
206
ifconfig_pool_handle
184
ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, const char *common_name)
207
ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name)
185
{
208
{
186
  int i;
209
  int i;
187
210
Lines 214-219 Link Here
214
	default:
237
	default:
215
	  ASSERT (0);
238
	  ASSERT (0);
216
	}
239
	}
240
241
      /* IPv6 pools are always INDIV (--linear) */
242
      if ( pool->ipv6 && remote_ipv6 )
243
	{
244
	  *remote_ipv6 = add_in6_addr( pool->base_ipv6, i );
245
	}
217
    }
246
    }
218
  return i;
247
  return i;
219
}
248
}
Lines 288-293 Link Here
288
  return ret;
317
  return ret;
289
}
318
}
290
319
320
static struct in6_addr
321
ifconfig_pool_handle_to_ipv6_base (const struct ifconfig_pool* pool, ifconfig_pool_handle hand)
322
{
323
  struct in6_addr ret = in6addr_any;
324
325
  /* IPv6 pools are always INDIV (--linear) */
326
  if (hand >= 0 && hand < pool->size_ipv6 )
327
    {
328
      ret = add_in6_addr( pool->base_ipv6, hand );
329
    }
330
  return ret;
331
}
332
291
static void
333
static void
292
ifconfig_pool_set (struct ifconfig_pool* pool, const char *cn, const in_addr_t addr, const bool fixed)
334
ifconfig_pool_set (struct ifconfig_pool* pool, const char *cn, const in_addr_t addr, const bool fixed)
293
{
335
{
Lines 317-325 Link Here
317
	  if (e->common_name)
359
	  if (e->common_name)
318
	    {
360
	    {
319
	      const in_addr_t ip = ifconfig_pool_handle_to_ip_base (pool, i);
361
	      const in_addr_t ip = ifconfig_pool_handle_to_ip_base (pool, i);
320
	      status_printf (out, "%s,%s",
362
	      if ( pool->ipv6 )
321
			     e->common_name,
363
		{
322
			     print_in_addr_t (ip, 0, &gc));
364
		  struct in6_addr ip6 = ifconfig_pool_handle_to_ipv6_base (pool, i);
365
		  status_printf (out, "%s,%s,%s",
366
				 e->common_name,
367
				 print_in_addr_t (ip, 0, &gc),
368
				 print_in6_addr (ip6, 0, &gc));
369
		}
370
	      else
371
		{
372
		  status_printf (out, "%s,%s",
373
				 e->common_name,
374
				 print_in_addr_t (ip, 0, &gc));
375
		}
323
	    }
376
	    }
324
	}
377
	}
325
      gc_free (&gc);
378
      gc_free (&gc);
Lines 409-414 Link Here
409
	      int c = *BSTR(&in);
462
	      int c = *BSTR(&in);
410
	      if (c == '#' || c == ';')
463
	      if (c == '#' || c == ';')
411
		continue;
464
		continue;
465
	      msg( M_INFO, "ifconfig_pool_read(), in='%s', TODO: IPv6",
466
				BSTR(&in) );
467
412
	      if (buf_parse (&in, ',', cn_buf, buf_size)
468
	      if (buf_parse (&in, ',', cn_buf, buf_size)
413
		  && buf_parse (&in, ',', ip_buf, buf_size))
469
		  && buf_parse (&in, ',', ip_buf, buf_size))
414
		{
470
		{
Lines 416-421 Link Here
416
		  const in_addr_t addr = getaddr (GETADDR_HOST_ORDER, ip_buf, 0, &succeeded, NULL);
472
		  const in_addr_t addr = getaddr (GETADDR_HOST_ORDER, ip_buf, 0, &succeeded, NULL);
417
		  if (succeeded)
473
		  if (succeeded)
418
		    {
474
		    {
475
		      msg( M_INFO, "succeeded -> ifconfig_pool_set()");
419
		      ifconfig_pool_set (pool, cn_buf, addr, persist->fixed);
476
		      ifconfig_pool_set (pool, cn_buf, addr, persist->fixed);
420
		    }
477
		    }
421
		}
478
		}
Lines 471-477 Link Here
471
#else
528
#else
472
      cn = buf;
529
      cn = buf;
473
#endif
530
#endif
474
      h = ifconfig_pool_acquire (p, &local, &remote, cn);
531
      h = ifconfig_pool_acquire (p, &local, &remote, NULL, cn);
475
      if (h < 0)
532
      if (h < 0)
476
	break;
533
	break;
477
      msg (M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 1: l=%s r=%s cn=%s",
534
      msg (M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 1: l=%s r=%s cn=%s",
Lines 506-512 Link Here
506
#else
563
#else
507
      cn = buf;
564
      cn = buf;
508
#endif
565
#endif
509
      h = ifconfig_pool_acquire (p, &local, &remote, cn);
566
      h = ifconfig_pool_acquire (p, &local, &remote, NULL, cn);
510
      if (h < 0)
567
      if (h < 0)
511
	break;
568
	break;
512
      msg (M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 3: l=%s r=%s cn=%s",
569
      msg (M_INFO | M_NOPREFIX, "IFCONFIG_POOL TEST pass 3: l=%s r=%s cn=%s",
(-)openvpn-2.2.2_unpatched//pool.h (-2 / +5 lines)
Lines 52-57 Link Here
52
  int size;
52
  int size;
53
  int type;
53
  int type;
54
  bool duplicate_cn;
54
  bool duplicate_cn;
55
  bool ipv6;
56
  struct in6_addr base_ipv6;
57
  unsigned int size_ipv6;
55
  struct ifconfig_pool_entry *list;
58
  struct ifconfig_pool_entry *list;
56
};
59
};
57
60
Lines 63-75 Link Here
63
66
64
typedef int ifconfig_pool_handle;
67
typedef int ifconfig_pool_handle;
65
68
66
struct ifconfig_pool *ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn);
69
struct ifconfig_pool *ifconfig_pool_init (int type, in_addr_t start, in_addr_t end, const bool duplicate_cn, const bool ipv6_pool, const struct in6_addr ipv6_base, const int ipv6_netbits );
67
70
68
void ifconfig_pool_free (struct ifconfig_pool *pool);
71
void ifconfig_pool_free (struct ifconfig_pool *pool);
69
72
70
bool ifconfig_pool_verify_range (const int msglevel, const in_addr_t start, const in_addr_t end);
73
bool ifconfig_pool_verify_range (const int msglevel, const in_addr_t start, const in_addr_t end);
71
74
72
ifconfig_pool_handle ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, const char *common_name);
75
ifconfig_pool_handle ifconfig_pool_acquire (struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name);
73
76
74
bool ifconfig_pool_release (struct ifconfig_pool* pool, ifconfig_pool_handle hand, const bool hard);
77
bool ifconfig_pool_release (struct ifconfig_pool* pool, ifconfig_pool_handle hand, const bool hard);
75
78
(-)openvpn-2.2.2_unpatched//proto.h (+15 lines)
Lines 108-113 Link Here
108
};
108
};
109
109
110
/*
110
/*
111
 * IPv6 header
112
 */
113
struct openvpn_ipv6hdr {
114
        uint8_t		version_prio;
115
        uint8_t		flow_lbl[3];
116
        uint16_t	payload_len;
117
        uint8_t		nexthdr;
118
        uint8_t		hop_limit;
119
120
        struct  in6_addr        saddr;
121
        struct  in6_addr        daddr;
122
};
123
124
125
/*
111
 * UDP header
126
 * UDP header
112
 */
127
 */
113
struct openvpn_udphdr {
128
struct openvpn_udphdr {
(-)openvpn-2.2.2_unpatched//push.c (+18 lines)
Lines 189-196 Link Here
189
  const int safe_cap = BCAP (&buf) - extra;
189
  const int safe_cap = BCAP (&buf) - extra;
190
  bool push_sent = false;
190
  bool push_sent = false;
191
191
192
  msg( M_INFO, "send_push_reply(): safe_cap=%d", safe_cap );
193
192
  buf_printf (&buf, "%s", cmd);
194
  buf_printf (&buf, "%s", cmd);
193
195
196
  if ( c->c2.push_ifconfig_ipv6_defined )
197
    {
198
      /* IPv6 is put into buffer first, could be lengthy */
199
      /* TODO: push "/netbits" as well, to allow non-/64 subnet sizes
200
       *       (needs changes in options.c, options.h, and other places)
201
       */
202
      buf_printf( &buf, ",ifconfig-ipv6 %s %s",
203
		    print_in6_addr( c->c2.push_ifconfig_ipv6_local, 0, &gc),
204
		    print_in6_addr( c->c2.push_ifconfig_ipv6_remote, 0, &gc) );
205
      if (BLEN (&buf) >= safe_cap)
206
	{
207
	  msg (M_WARN, "--push ifconfig-ipv6 option is too long");
208
	  goto fail;
209
	}
210
    }
211
194
  while (e)
212
  while (e)
195
    {
213
    {
196
      if (e->enable)
214
      if (e->enable)
(-)openvpn-2.2.2_unpatched//route.c (-7 / +562 lines)
Lines 35-40 Link Here
35
#include "socket.h"
35
#include "socket.h"
36
#include "manage.h"
36
#include "manage.h"
37
#include "win32.h"
37
#include "win32.h"
38
#include "options.h"
38
39
39
#include "memdbg.h"
40
#include "memdbg.h"
40
41
Lines 68-73 Link Here
68
  return ret;
69
  return ret;
69
}
70
}
70
71
72
struct route_ipv6_option_list *
73
new_route_ipv6_option_list (const int max_routes, struct gc_arena *a)
74
{
75
  struct route_ipv6_option_list *ret;
76
  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_option_list, struct route_ipv6_option, max_routes, a);
77
  ret->capacity = max_routes;
78
  return ret;
79
}
80
71
struct route_option_list *
81
struct route_option_list *
72
clone_route_option_list (const struct route_option_list *src, struct gc_arena *a)
82
clone_route_option_list (const struct route_option_list *src, struct gc_arena *a)
73
{
83
{
Lines 95-100 Link Here
95
  return ret;
105
  return ret;
96
}
106
}
97
107
108
struct route_ipv6_list *
109
new_route_ipv6_list (const int max_routes, struct gc_arena *a)
110
{
111
  struct route_ipv6_list *ret;
112
  ALLOC_VAR_ARRAY_CLEAR_GC (ret, struct route_ipv6_list, struct route_ipv6, max_routes, a);
113
  ret->capacity = max_routes;
114
  return ret;
115
}
116
98
static const char *
117
static const char *
99
route_string (const struct route *r, struct gc_arena *gc)
118
route_string (const struct route *r, struct gc_arena *gc)
100
{
119
{
Lines 311-316 Link Here
311
  return false;
330
  return false;
312
}
331
}
313
332
333
static bool
334
init_route_ipv6 (struct route_ipv6 *r6,
335
	         const struct route_ipv6_option *r6o,
336
	         const struct route_ipv6_list *rl6 )
337
{
338
  r6->option = r6o;
339
  r6->defined = false;
340
341
  if ( !get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, NULL, M_WARN ))
342
    goto fail;
343
344
  /* gateway */
345
  if (is_route_parm_defined (r6o->gateway))
346
    {
347
      if ( inet_pton( AF_INET6, r6o->gateway, &r6->gateway ) != 1 )
348
        {
349
	  msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway );
350
        }
351
    }
352
  else if (rl6->remote_endpoint_defined)
353
    {
354
      r6->gateway = rl6->remote_endpoint_ipv6;
355
    }
356
  else
357
    {
358
      msg (M_WARN, PACKAGE_NAME " ROUTE6: " PACKAGE_NAME " needs a gateway parameter for a --route-ipv6 option and no default was specified by either --route-ipv6-gateway or --ifconfig-ipv6 options");
359
      goto fail;
360
    }
361
362
  /* metric */
363
364
  r6->metric_defined = false;
365
  r6->metric = 0;
366
  if (is_route_parm_defined (r6o->metric))
367
    {
368
      r6->metric = atoi (r6o->metric);
369
      if (r6->metric < 0)
370
	{
371
	  msg (M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
372
	       r6o->prefix,
373
	       r6o->metric);
374
	  goto fail;
375
	}
376
      r6->metric_defined = true;
377
    }
378
  else if (rl6->default_metric_defined)
379
    {
380
      r6->metric = rl6->default_metric;
381
      r6->metric_defined = true;
382
    }
383
384
  r6->defined = true;
385
386
  return true;
387
388
 fail:
389
  msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
390
       r6o->prefix);
391
  r6->defined = false;
392
  return false;
393
}
394
314
void
395
void
315
add_route_to_option_list (struct route_option_list *l,
396
add_route_to_option_list (struct route_option_list *l,
316
			  const char *network,
397
			  const char *network,
Lines 331-336 Link Here
331
}
412
}
332
413
333
void
414
void
415
add_route_ipv6_to_option_list (struct route_ipv6_option_list *l,
416
			  const char *prefix,
417
			  const char *gateway,
418
			  const char *metric)
419
{
420
  struct route_ipv6_option *ro;
421
  if (l->n >= l->capacity)
422
    msg (M_FATAL, PACKAGE_NAME " ROUTE: cannot add more than %d IPv6 routes -- please increase the max-routes option in the client configuration file",
423
	 l->capacity);
424
  ro = &l->routes_ipv6[l->n];
425
  ro->prefix = prefix;
426
  ro->gateway = gateway;
427
  ro->metric = metric;
428
  ++l->n;
429
}
430
431
void
334
clear_route_list (struct route_list *rl)
432
clear_route_list (struct route_list *rl)
335
{
433
{
336
  const int capacity = rl->capacity;
434
  const int capacity = rl->capacity;
Lines 340-345 Link Here
340
}
438
}
341
439
342
void
440
void
441
clear_route_ipv6_list (struct route_ipv6_list *rl6)
442
{
443
  const int capacity = rl6->capacity;
444
  const size_t rl6_size = array_mult_safe (sizeof(struct route_ipv6), capacity, sizeof(struct route_ipv6_list));
445
  memset(rl6, 0, rl6_size);
446
  rl6->capacity = capacity;
447
}
448
449
void
343
route_list_add_default_gateway (struct route_list *rl,
450
route_list_add_default_gateway (struct route_list *rl,
344
				struct env_set *es,
451
				struct env_set *es,
345
				const in_addr_t addr)
452
				const in_addr_t addr)
Lines 469-474 Link Here
469
  return ret;
576
  return ret;
470
}
577
}
471
578
579
bool
580
init_route_ipv6_list (struct route_ipv6_list *rl6,
581
		 const struct route_ipv6_option_list *opt6,
582
		 const char *remote_endpoint,
583
		 int default_metric,
584
		 struct env_set *es)
585
{
586
  struct gc_arena gc = gc_new ();
587
  bool ret = true;
588
589
  clear_route_ipv6_list (rl6);
590
591
  rl6->flags = opt6->flags;
592
593
  if (default_metric)
594
    {
595
      rl6->default_metric = default_metric;
596
      rl6->default_metric_defined = true;
597
    }
598
599
  /* "default_gateway" is stuff for "redirect-gateway", which we don't
600
   * do for IPv6 yet -> TODO
601
   */
602
    {
603
      dmsg (D_ROUTE, "ROUTE6: default_gateway=UNDEF");
604
    }
605
606
  if ( is_route_parm_defined( remote_endpoint ))
607
    {
608
      if ( inet_pton( AF_INET6, remote_endpoint, 
609
			&rl6->remote_endpoint_ipv6) == 1 )
610
        {
611
	  rl6->remote_endpoint_defined = true;
612
        }
613
      else
614
	{
615
	  msg (M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s", remote_endpoint);
616
          ret = false;
617
	}
618
    }
619
  else
620
    rl6->remote_endpoint_defined = false;
621
622
623
  if (!(opt6->n >= 0 && opt6->n <= rl6->capacity))
624
    msg (M_FATAL, PACKAGE_NAME " ROUTE6: (init) number of route options (%d) is greater than route list capacity (%d)", opt6->n, rl6->capacity);
625
626
  /* parse the routes from opt to rl6 */
627
  {
628
    int i, j = 0;
629
    for (i = 0; i < opt6->n; ++i)
630
      {
631
	if (!init_route_ipv6 (&rl6->routes_ipv6[j],
632
			      &opt6->routes_ipv6[i],
633
			      rl6 ))
634
	  ret = false;
635
	else
636
	  ++j;
637
      }
638
    rl6->n = j;
639
  }
640
641
  gc_free (&gc);
642
  return ret;
643
}
644
472
static void
645
static void
473
add_route3 (in_addr_t network,
646
add_route3 (in_addr_t network,
474
	    in_addr_t netmask,
647
	    in_addr_t netmask,
Lines 704-713 Link Here
704
}
877
}
705
878
706
void
879
void
707
add_routes (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
880
add_routes (struct route_list *rl, struct route_ipv6_list *rl6,
881
	    const struct tuntap *tt, unsigned int flags, const struct env_set *es)
708
{
882
{
709
  redirect_default_route_to_vpn (rl, tt, flags, es);
883
  if (rl) 
710
  if (!rl->routes_added)
884
      redirect_default_route_to_vpn (rl, tt, flags, es);
885
886
  if (rl && !rl->routes_added)
711
    {
887
    {
712
      int i;
888
      int i;
713
889
Lines 732-743 Link Here
732
	}
908
	}
733
      rl->routes_added = true;
909
      rl->routes_added = true;
734
    }
910
    }
911
912
  if (rl6 && !rl6->routes_added)
913
    {
914
      int i;
915
916
      for (i = 0; i < rl6->n; ++i)
917
	{
918
	  struct route_ipv6 *r = &rl6->routes_ipv6[i];
919
	  if (flags & ROUTE_DELETE_FIRST)
920
	    delete_route_ipv6 (r, tt, flags, es);
921
	  add_route_ipv6 (r, tt, flags, es);
922
	}
923
      rl6->routes_added = true;
924
    }
735
}
925
}
736
926
737
void
927
void
738
delete_routes (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
928
delete_routes (struct route_list *rl, struct route_ipv6_list *rl6,
929
	       const struct tuntap *tt, unsigned int flags, const struct env_set *es)
739
{
930
{
740
  if (rl->routes_added)
931
  if (rl && rl->routes_added)
741
    {
932
    {
742
      int i;
933
      int i;
743
      for (i = rl->n - 1; i >= 0; --i)
934
      for (i = rl->n - 1; i >= 0; --i)
Lines 747-755 Link Here
747
	}
938
	}
748
      rl->routes_added = false;
939
      rl->routes_added = false;
749
    }
940
    }
750
  undo_redirect_default_route_to_vpn (rl, tt, flags, es);
751
941
752
  clear_route_list (rl);
942
  if ( rl )
943
    {
944
      undo_redirect_default_route_to_vpn (rl, tt, flags, es);
945
      clear_route_list (rl);
946
    }
947
948
  if ( rl6 && rl6->routes_added )
949
    {
950
      int i;
951
      for (i = rl6->n - 1; i >= 0; --i)
952
	{
953
	  const struct route_ipv6 *r6 = &rl6->routes_ipv6[i];
954
	  delete_route_ipv6 (r6, tt, flags, es);
955
	}
956
      rl6->routes_added = false;
957
    }
958
959
  if ( rl6 )
960
    {
961
      clear_route_ipv6_list (rl6);
962
    }
753
}
963
}
754
964
755
#ifdef ENABLE_DEBUG
965
#ifdef ENABLE_DEBUG
Lines 832-837 Link Here
832
    setenv_route (es, &rl->routes[i], i + 1);
1042
    setenv_route (es, &rl->routes[i], i + 1);
833
}
1043
}
834
1044
1045
static void
1046
setenv_route_ipv6 (struct env_set *es, const struct route_ipv6 *r6, int i)
1047
{
1048
  struct gc_arena gc = gc_new ();
1049
  if (r6->defined)
1050
    {
1051
      struct buffer name1 = alloc_buf_gc( 256, &gc );
1052
      struct buffer val = alloc_buf_gc( 256, &gc );
1053
      struct buffer name2 = alloc_buf_gc( 256, &gc );
1054
1055
      buf_printf( &name1, "route_ipv6_network_%d", i );
1056
      buf_printf( &val, "%s/%d", print_in6_addr( r6->network, 0, &gc ),
1057
				 r6->netbits );
1058
      setenv_str( es, BSTR(&name1), BSTR(&val) );
1059
1060
      buf_printf( &name2, "route_ipv6_gateway_%d", i );
1061
      setenv_str( es, BSTR(&name2), print_in6_addr( r6->gateway, 0, &gc ));
1062
    }
1063
  gc_free (&gc);
1064
}
1065
void
1066
setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6)
1067
{
1068
  int i;
1069
  for (i = 0; i < rl6->n; ++i)
1070
    setenv_route_ipv6 (es, &rl6->routes_ipv6[i], i + 1);
1071
}
1072
835
void
1073
void
836
add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1074
add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
837
{
1075
{
Lines 1025-1030 Link Here
1025
  gc_free (&gc);
1263
  gc_free (&gc);
1026
}
1264
}
1027
1265
1266
1267
static const char * 
1268
print_in6_addr_netbits_only( struct in6_addr network_copy, int netbits, 
1269
                             struct gc_arena * gc)
1270
{
1271
  /* clear host bit parts of route 
1272
   * (needed if routes are specified improperly, or if we need to 
1273
   * explicitely setup/clear the "connected" network routes on some OSes)
1274
   */
1275
  int byte = 15;
1276
  int bits_to_clear = 128 - netbits;
1277
1278
  while( byte >= 0 && bits_to_clear > 0 )
1279
    {
1280
      if ( bits_to_clear >= 8 )
1281
	{ network_copy.s6_addr[byte--] = 0; bits_to_clear -= 8; }
1282
      else
1283
	{ network_copy.s6_addr[byte--] &= (~0 << bits_to_clear); bits_to_clear = 0; }
1284
    }
1285
1286
  return print_in6_addr( network_copy, 0, gc);
1287
}
1288
1289
void
1290
add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1291
{
1292
  struct gc_arena gc;
1293
  struct argv argv;
1294
1295
  const char *network;
1296
  const char *gateway;
1297
  bool status = false;
1298
  const char *device = tt->actual_name;
1299
1300
  if (!r6->defined)
1301
    return;
1302
1303
  gc_init (&gc);
1304
  argv_init (&argv);
1305
1306
  network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc);
1307
  gateway = print_in6_addr( r6->gateway, 0, &gc);
1308
1309
  if ( !tt->ipv6 )
1310
    {
1311
      msg( M_INFO, "add_route_ipv6(): not adding %s/%d, no IPv6 on if %s",
1312
		    network, r6->netbits, device );
1313
      return;
1314
    }
1315
1316
  msg( M_INFO, "add_route_ipv6(%s/%d -> %s metric %d) dev %s",
1317
		network, r6->netbits, gateway, r6->metric, device );
1318
1319
  /*
1320
   * Filter out routes which are essentially no-ops
1321
   * (not currently done for IPv6)
1322
   */
1323
1324
#if defined(TARGET_LINUX)
1325
#ifdef CONFIG_FEATURE_IPROUTE
1326
  argv_printf (&argv, "%s -6 route add %s/%d dev %s",
1327
  	      iproute_path,
1328
	      network,
1329
	      r6->netbits,
1330
	      device);
1331
  if (r6->metric_defined)
1332
    argv_printf_cat (&argv, " metric %d", r6->metric);
1333
1334
#else
1335
  argv_printf (&argv, "%s -A inet6 add %s/%d dev %s",
1336
		ROUTE_PATH,
1337
	      network,
1338
	      r6->netbits,
1339
	      device);
1340
  if (r6->metric_defined)
1341
    argv_printf_cat (&argv, " metric %d", r6->metric);
1342
#endif  /*CONFIG_FEATURE_IPROUTE*/
1343
  argv_msg (D_ROUTE, &argv);
1344
  status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 add command failed");
1345
1346
#elif defined (WIN32)
1347
1348
  /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
1349
  argv_printf (&argv, "%s%sc interface ipv6 add route %s/%d %s",
1350
	       get_win_sys_path(),
1351
	       NETSH_PATH_SUFFIX,
1352
	       network,
1353
	       r6->netbits,
1354
	       device);
1355
1356
  /* next-hop depends on TUN or TAP mode:
1357
   * - in TAP mode, we use the "real" next-hop
1358
   * - in TUN mode we use a special-case link-local address that the tapdrvr
1359
   *   knows about and will answer ND (neighbor discovery) packets for
1360
   */
1361
  if ( tt->type == DEV_TYPE_TUN )
1362
	argv_printf_cat( &argv, " %s", "fe80::8" );
1363
  else
1364
	argv_printf_cat( &argv, " %s", gateway );
1365
1366
#if 0
1367
  if (r->metric_defined)
1368
    argv_printf_cat (&argv, " METRIC %d", r->metric);
1369
#endif
1370
1371
  /* in some versions of Windows, routes are persistent across reboots by
1372
   * default, unless "store=active" is set (pointed out by Tony Lim, thanks)
1373
   */
1374
  argv_printf_cat( &argv, " store=active" );
1375
1376
  argv_msg (D_ROUTE, &argv);
1377
1378
  netcmd_semaphore_lock ();
1379
  status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
1380
  netcmd_semaphore_release ();
1381
1382
#elif defined (TARGET_SOLARIS)
1383
1384
  /* example: route add -inet6 2001:db8::/32 somegateway 0 */
1385
1386
  /* for some weird reason, this does not work for me unless I set
1387
   * "metric 0" - otherwise, the routes will be nicely installed, but
1388
   * packets will just disappear somewhere.  So we use "0" now...
1389
   */
1390
1391
  argv_printf (&argv, "%s add -inet6 %s/%d %s 0",
1392
		ROUTE_PATH,
1393
		network,
1394
		r6->netbits,
1395
		gateway );
1396
1397
  argv_msg (D_ROUTE, &argv);
1398
  status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add -inet6 command failed");
1399
1400
#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1401
1402
  argv_printf (&argv, "%s add -inet6 %s/%d -iface %s",
1403
		ROUTE_PATH,
1404
	        network,
1405
	        r6->netbits,
1406
	        device );
1407
1408
  argv_msg (D_ROUTE, &argv);
1409
  status = openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route add -inet6 command failed");
1410
1411
#elif defined(TARGET_DARWIN) 
1412
1413
  argv_printf (&argv, "%s add -inet6 %s -prefixlen %d -iface %s",
1414
		ROUTE_PATH,
1415
	        network, r6->netbits, device );
1416
1417
  argv_msg (D_ROUTE, &argv);
1418
  status = openvpn_execve_check (&argv, es, 0, "ERROR: MacOS X route add -inet6 command failed");
1419
1420
#elif defined(TARGET_OPENBSD)
1421
1422
  argv_printf (&argv, "%s add -inet6 %s -prefixlen %d %s",
1423
		ROUTE_PATH,
1424
	        network, r6->netbits, gateway );
1425
1426
  argv_msg (D_ROUTE, &argv);
1427
  status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route add -inet6 command failed");
1428
1429
#elif defined(TARGET_NETBSD)
1430
1431
  argv_printf (&argv, "%s add -inet6 %s/%d %s",
1432
		ROUTE_PATH,
1433
	        network, r6->netbits, gateway );
1434
1435
  argv_msg (D_ROUTE, &argv);
1436
  status = openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route add -inet6 command failed");
1437
1438
#else
1439
  msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system.  Try putting your routes in a --route-up script");
1440
#endif
1441
1442
  r6->defined = status;
1443
  argv_reset (&argv);
1444
  gc_free (&gc);
1445
}
1446
1028
static void
1447
static void
1029
delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1448
delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1030
{
1449
{
Lines 1161-1166 Link Here
1161
#endif
1580
#endif
1162
1581
1163
  argv_reset (&argv);
1582
  argv_reset (&argv);
1583
  gc_free (&gc);
1584
}
1585
1586
void
1587
delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1588
{
1589
  struct gc_arena gc;
1590
  struct argv argv;
1591
  const char *network;
1592
  const char *gateway;
1593
  const char *device = tt->actual_name;
1594
1595
  if (!r6->defined)
1596
    return;
1597
1598
  gc_init (&gc);
1599
  argv_init (&argv);
1600
1601
  network = print_in6_addr_netbits_only( r6->network, r6->netbits, &gc);
1602
  gateway = print_in6_addr( r6->gateway, 0, &gc);
1603
1604
  if ( !tt->ipv6 )
1605
    {
1606
      msg( M_INFO, "delete_route_ipv6(): not deleting %s/%d, no IPv6 on if %s",
1607
		    network, r6->netbits, device );
1608
      return;
1609
    }
1610
1611
  msg( M_INFO, "delete_route_ipv6(%s/%d)", network, r6->netbits );
1612
1613
#if defined(TARGET_LINUX)
1614
#ifdef CONFIG_FEATURE_IPROUTE
1615
  argv_printf (&argv, "%s -6 route del %s/%d dev %s",
1616
  	      iproute_path,
1617
	      network,
1618
	      r6->netbits,
1619
	      device);
1620
#else
1621
  argv_printf (&argv, "%s -A inet6 del %s/%d dev %s",
1622
		ROUTE_PATH,
1623
	      network,
1624
	      r6->netbits,
1625
	      device);
1626
#endif  /*CONFIG_FEATURE_IPROUTE*/
1627
  argv_msg (D_ROUTE, &argv);
1628
  openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 del command failed");
1629
1630
#elif defined (WIN32)
1631
1632
  /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
1633
  argv_printf (&argv, "%s%sc interface ipv6 delete route %s/%d %s",
1634
	       get_win_sys_path(),
1635
	       NETSH_PATH_SUFFIX,
1636
	       network,
1637
	       r6->netbits,
1638
	       device);
1639
1640
  /* next-hop depends on TUN or TAP mode:
1641
   * - in TAP mode, we use the "real" next-hop
1642
   * - in TUN mode we use a special-case link-local address that the tapdrvr
1643
   *   knows about and will answer ND (neighbor discovery) packets for
1644
   * (and "route deletion without specifying next-hop" does not work...)
1645
   */
1646
  if ( tt->type == DEV_TYPE_TUN )
1647
	argv_printf_cat( &argv, " %s", "fe80::8" );
1648
  else
1649
	argv_printf_cat( &argv, " %s", gateway );
1650
1651
#if 0
1652
  if (r->metric_defined)
1653
    argv_printf_cat (&argv, "METRIC %d", r->metric);
1654
#endif
1655
1656
  argv_msg (D_ROUTE, &argv);
1657
1658
  netcmd_semaphore_lock ();
1659
  openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
1660
  netcmd_semaphore_release ();
1661
1662
#elif defined (TARGET_SOLARIS)
1663
1664
  /* example: route delete -inet6 2001:db8::/32 somegateway */
1665
  /* GERT-TODO: this is untested, but should work */
1666
1667
  argv_printf (&argv, "%s delete -inet6 %s/%d %s",
1668
		ROUTE_PATH,
1669
		network,
1670
		r6->netbits,
1671
		gateway );
1672
1673
  argv_msg (D_ROUTE, &argv);
1674
  openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed");
1675
1676
#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1677
1678
  argv_printf (&argv, "%s delete -inet6 %s/%d -iface %s",
1679
		ROUTE_PATH,
1680
	        network,
1681
	        r6->netbits,
1682
	        device );
1683
1684
  argv_msg (D_ROUTE, &argv);
1685
  openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed");
1686
1687
#elif defined(TARGET_DARWIN) 
1688
1689
  argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d -iface %s",
1690
		ROUTE_PATH, 
1691
		network, r6->netbits, device );
1692
1693
  argv_msg (D_ROUTE, &argv);
1694
  openvpn_execve_check (&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed");
1695
1696
#elif defined(TARGET_OPENBSD)
1697
1698
  argv_printf (&argv, "%s delete -inet6 %s -prefixlen %d %s",
1699
		ROUTE_PATH,
1700
	        network, r6->netbits, gateway );
1701
1702
  argv_msg (D_ROUTE, &argv);
1703
  openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD route delete -inet6 command failed");
1704
1705
#elif defined(TARGET_NETBSD)
1706
1707
  argv_printf (&argv, "%s delete -inet6 %s/%d %s",
1708
		ROUTE_PATH,
1709
	        network, r6->netbits, gateway );
1710
1711
  argv_msg (D_ROUTE, &argv);
1712
  openvpn_execve_check (&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed");
1713
1714
#else
1715
  msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system.  Try putting your routes in a --route-down script");
1716
#endif
1717
1718
  argv_reset (&argv);
1164
  gc_free (&gc);
1719
  gc_free (&gc);
1165
}
1720
}
1166
1721
(-)openvpn-2.2.2_unpatched//route.h (+62 lines)
Lines 92-97 Link Here
92
  struct route_option routes[EMPTY_ARRAY_SIZE];
92
  struct route_option routes[EMPTY_ARRAY_SIZE];
93
};
93
};
94
94
95
struct route_ipv6_option {
96
  const char *prefix;		/* e.g. "2001:db8:1::/64" */
97
  const char *gateway;		/* e.g. "2001:db8:0::2" */
98
  const char *metric;		/* e.g. "5" */
99
};
100
101
struct route_ipv6_option_list {
102
  unsigned int flags;
103
  int capacity;
104
  int n;
105
  struct route_ipv6_option routes_ipv6[EMPTY_ARRAY_SIZE];
106
};
107
95
struct route {
108
struct route {
96
  bool defined;
109
  bool defined;
97
  const struct route_option *option;
110
  const struct route_option *option;
Lines 113-118 Link Here
113
  struct route routes[EMPTY_ARRAY_SIZE];
126
  struct route routes[EMPTY_ARRAY_SIZE];
114
};
127
};
115
128
129
struct route_ipv6 {
130
  bool defined;
131
  const struct route_ipv6_option *option;
132
  struct in6_addr network;
133
  unsigned int netbits;
134
  struct in6_addr gateway;
135
  bool metric_defined;
136
  int metric;
137
};
138
139
struct route_ipv6_list {
140
  bool routes_added;
141
  unsigned int flags;
142
  int default_metric;
143
  bool default_metric_defined;
144
  struct in6_addr remote_endpoint_ipv6;
145
  bool remote_endpoint_defined;
146
  bool did_redirect_default_gateway;			/* TODO (?) */
147
  bool did_local;					/* TODO (?) */
148
  int capacity;
149
  int n;
150
  struct route_ipv6 routes_ipv6[EMPTY_ARRAY_SIZE];
151
};
152
153
116
#if P2MP
154
#if P2MP
117
/* internal OpenVPN route */
155
/* internal OpenVPN route */
118
struct iroute {
156
struct iroute {
Lines 120-134 Link Here
120
  int netbits;
158
  int netbits;
121
  struct iroute *next;
159
  struct iroute *next;
122
};
160
};
161
162
struct iroute_ipv6 {
163
  struct in6_addr network;
164
  unsigned int netbits;
165
  struct iroute_ipv6 *next;
166
};
123
#endif
167
#endif
124
168
125
struct route_option_list *new_route_option_list (const int max_routes, struct gc_arena *a);
169
struct route_option_list *new_route_option_list (const int max_routes, struct gc_arena *a);
170
struct route_ipv6_option_list *new_route_ipv6_option_list (const int max_routes, struct gc_arena *a);
126
struct route_option_list *clone_route_option_list (const struct route_option_list *src, struct gc_arena *a);
171
struct route_option_list *clone_route_option_list (const struct route_option_list *src, struct gc_arena *a);
127
void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src);
172
void copy_route_option_list (struct route_option_list *dest, const struct route_option_list *src);
128
173
129
struct route_list *new_route_list (const int max_routes, struct gc_arena *a);
174
struct route_list *new_route_list (const int max_routes, struct gc_arena *a);
175
struct route_ipv6_list *new_route_ipv6_list (const int max_routes, struct gc_arena *a);
130
176
131
void add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
177
void add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
178
void add_route_ipv6 (struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
179
void delete_route_ipv6 (const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
132
180
133
void add_route_to_option_list (struct route_option_list *l,
181
void add_route_to_option_list (struct route_option_list *l,
134
			       const char *network,
182
			       const char *network,
Lines 136-141 Link Here
136
			       const char *gateway,
184
			       const char *gateway,
137
			       const char *metric);
185
			       const char *metric);
138
186
187
void add_route_ipv6_to_option_list (struct route_ipv6_option_list *l,
188
			       const char *prefix,
189
			       const char *gateway,
190
			       const char *metric);
191
139
bool init_route_list (struct route_list *rl,
192
bool init_route_list (struct route_list *rl,
140
		      const struct route_option_list *opt,
193
		      const struct route_option_list *opt,
141
		      const char *remote_endpoint,
194
		      const char *remote_endpoint,
Lines 143-163 Link Here
143
		      in_addr_t remote_host,
196
		      in_addr_t remote_host,
144
		      struct env_set *es);
197
		      struct env_set *es);
145
198
199
bool init_route_ipv6_list (struct route_ipv6_list *rl6,
200
		      const struct route_ipv6_option_list *opt6,
201
		      const char *remote_endpoint,
202
		      int default_metric,
203
		      struct env_set *es);
204
146
void route_list_add_default_gateway (struct route_list *rl,
205
void route_list_add_default_gateway (struct route_list *rl,
147
				     struct env_set *es,
206
				     struct env_set *es,
148
				     const in_addr_t addr);
207
				     const in_addr_t addr);
149
208
150
void add_routes (struct route_list *rl,
209
void add_routes (struct route_list *rl,
210
		 struct route_ipv6_list *rl6,
151
		 const struct tuntap *tt,
211
		 const struct tuntap *tt,
152
		 unsigned int flags,
212
		 unsigned int flags,
153
		 const struct env_set *es);
213
		 const struct env_set *es);
154
214
155
void delete_routes (struct route_list *rl,
215
void delete_routes (struct route_list *rl,
216
		    struct route_ipv6_list *rl6,
156
		    const struct tuntap *tt,
217
		    const struct tuntap *tt,
157
		    unsigned int flags,
218
		    unsigned int flags,
158
		    const struct env_set *es);
219
		    const struct env_set *es);
159
220
160
void setenv_routes (struct env_set *es, const struct route_list *rl);
221
void setenv_routes (struct env_set *es, const struct route_list *rl);
222
void setenv_routes_ipv6 (struct env_set *es, const struct route_ipv6_list *rl6);
161
223
162
bool is_special_addr (const char *addr_str);
224
bool is_special_addr (const char *addr_str);
163
225
(-)openvpn-2.2.2_unpatched//socket.c (+119 lines)
Lines 342-347 Link Here
342
  }
342
  }
343
}
343
}
344
344
345
bool
346
ipv6_addr_safe (const char *ipv6_text_addr)
347
{
348
  /* verify non-NULL */
349
  if (!ipv6_text_addr)
350
    return false;
351
352
  /* verify length is within limits */
353
  if (strlen (ipv6_text_addr) > INET6_ADDRSTRLEN )
354
    return false;
355
356
  /* verify that string will convert to IPv6 address */
357
  {
358
    struct in6_addr a6;
359
    return inet_pton( AF_INET6, ipv6_text_addr, &a6 ) == 1;
360
  }
361
}
362
345
static bool
363
static bool
346
dns_addr_safe (const char *addr)
364
dns_addr_safe (const char *addr)
347
{
365
{
Lines 2032-2037 Link Here
2032
  return BSTR (&out);
2050
  return BSTR (&out);
2033
}
2051
}
2034
2052
2053
/*
2054
 * Convert an in6_addr in host byte order
2055
 * to an ascii representation of an IPv6 address
2056
 */
2057
const char *
2058
print_in6_addr (struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
2059
{
2060
  struct buffer out = alloc_buf_gc (64, gc);
2061
  char tmp_out_buf[64];		/* inet_ntop wants pointer to buffer */
2062
2063
  if ( memcmp(&a6, &in6addr_any, sizeof(a6)) != 0 || 
2064
       !(flags & IA_EMPTY_IF_UNDEF))
2065
    {
2066
      inet_ntop (AF_INET6, &a6, tmp_out_buf, sizeof(tmp_out_buf)-1);
2067
      buf_printf (&out, "%s", tmp_out_buf );
2068
    }
2069
  return BSTR (&out);
2070
}
2071
2072
/* add some offset to an ipv6 address
2073
 * (add in steps of 32 bits, taking overflow into next round)
2074
 */
2075
#ifndef s6_addr32
2076
# ifdef TARGET_SOLARIS
2077
#  define s6_addr32 _S6_un._S6_u32
2078
# else
2079
#  define s6_addr32 __u6_addr.__u6_addr32
2080
# endif
2081
#endif
2082
#ifndef UINT32_MAX
2083
# define UINT32_MAX (4294967295U)
2084
#endif
2085
struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add )
2086
{
2087
    int i;
2088
    uint32_t h;
2089
2090
    for( i=3; i>=0 && add > 0 ; i-- )
2091
    {
2092
	h = ntohl( base.s6_addr32[i] );
2093
	base.s6_addr32[i] = htonl( (h+add) & UINT32_MAX );
2094
	/* 32-bit overrun? 
2095
	 * caveat: can't do "h+add > UINT32_MAX" with 32bit math!
2096
         */
2097
	add = ( h > UINT32_MAX - add )?  1: 0;
2098
    }
2099
    return base;
2100
}
2101
2035
/* set environmental variables for ip/port in *addr */
2102
/* set environmental variables for ip/port in *addr */
2036
void
2103
void
2037
setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openvpn_sockaddr *addr, const bool flags)
2104
setenv_sockaddr (struct env_set *es, const char *name_prefix, const struct openvpn_sockaddr *addr, const bool flags)
Lines 2337-2342 Link Here
2337
2404
2338
#ifdef WIN32
2405
#ifdef WIN32
2339
2406
2407
/*
2408
 * inet_ntop() and inet_pton() wrap-implementations using
2409
 * WSAAddressToString() and WSAStringToAddress() functions
2410
 */
2411
const char *
2412
inet_ntop(int af, const void *src, char *dst, socklen_t size)
2413
{
2414
  struct sockaddr_storage ss;
2415
  unsigned long s = size;
2416
2417
  CLEAR(ss);
2418
  ss.ss_family = af;
2419
2420
  switch(af) {
2421
    case AF_INET:
2422
      ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
2423
      break;
2424
    case AF_INET6:
2425
      ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
2426
      break;
2427
    default:
2428
      ASSERT (0);
2429
  }
2430
  // cannot direclty use &size because of strict aliasing rules
2431
  return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)?
2432
          dst : NULL;
2433
}
2434
2435
int
2436
inet_pton(int af, const char *src, void *dst)
2437
{
2438
  struct sockaddr_storage ss;
2439
  int size = sizeof(ss);
2440
  char src_copy[INET6_ADDRSTRLEN+1];
2441
2442
  CLEAR(ss);
2443
  // stupid non-const API
2444
  strncpynt(src_copy, src, INET6_ADDRSTRLEN+1);
2445
2446
  if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) {
2447
    switch(af) {
2448
      case AF_INET:
2449
	*(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
2450
	return 1;
2451
      case AF_INET6:
2452
	*(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
2453
	return 1;
2454
    }
2455
  }
2456
  return 0;
2457
}
2458
2340
int
2459
int
2341
socket_recv_queue (struct link_socket *sock, int maxsize)
2460
socket_recv_queue (struct link_socket *sock, int maxsize)
2342
{
2461
{
(-)openvpn-2.2.2_unpatched//socket.h (+3 lines)
Lines 351-356 Link Here
351
#define IA_EMPTY_IF_UNDEF (1<<0)
351
#define IA_EMPTY_IF_UNDEF (1<<0)
352
#define IA_NET_ORDER      (1<<1)
352
#define IA_NET_ORDER      (1<<1)
353
const char *print_in_addr_t (in_addr_t addr, unsigned int flags, struct gc_arena *gc);
353
const char *print_in_addr_t (in_addr_t addr, unsigned int flags, struct gc_arena *gc);
354
const char *print_in6_addr  (struct in6_addr addr6, unsigned int flags, struct gc_arena *gc);
355
struct in6_addr add_in6_addr( struct in6_addr base, uint32_t add );
354
356
355
#define SA_IP_PORT        (1<<0)
357
#define SA_IP_PORT        (1<<0)
356
#define SA_SET_IF_NONZERO (1<<1)
358
#define SA_SET_IF_NONZERO (1<<1)
Lines 404-409 Link Here
404
bool ip_addr_dotted_quad_safe (const char *dotted_quad);
406
bool ip_addr_dotted_quad_safe (const char *dotted_quad);
405
bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn);
407
bool ip_or_dns_addr_safe (const char *addr, const bool allow_fqdn);
406
bool mac_addr_safe (const char *mac_addr);
408
bool mac_addr_safe (const char *mac_addr);
409
bool ipv6_addr_safe (const char *ipv6_text_addr);
407
410
408
socket_descriptor_t create_socket_tcp (void);
411
socket_descriptor_t create_socket_tcp (void);
409
412
(-)openvpn-2.2.2_unpatched//syshead.h (+7 lines)
Lines 28-33 Link Here
28
/*
28
/*
29
 * Only include if not during configure
29
 * Only include if not during configure
30
 */
30
 */
31
#ifdef WIN32
32
/* USE_PF_INET6: win32 ipv6 exists only after 0x0501 (XP) */
33
#define WINVER 0x0501
34
#endif
31
#ifndef PACKAGE_NAME
35
#ifndef PACKAGE_NAME
32
#include "config.h"
36
#include "config.h"
33
#endif
37
#endif
Lines 339-344 Link Here
339
#ifdef WIN32
343
#ifdef WIN32
340
#include <iphlpapi.h>
344
#include <iphlpapi.h>
341
#include <wininet.h>
345
#include <wininet.h>
346
/* The following two headers are needed of USE_PF_INET6 */
347
#include <winsock2.h>
348
#include <ws2tcpip.h>
342
#endif
349
#endif
343
350
344
#ifdef HAVE_SYS_MMAN_H
351
#ifdef HAVE_SYS_MMAN_H
(-)openvpn-2.2.2_unpatched//tun.c (-66 / +514 lines)
Lines 56-68 Link Here
56
			    const in_addr_t ip,
56
			    const in_addr_t ip,
57
			    const in_addr_t netmask,
57
			    const in_addr_t netmask,
58
			    const unsigned int flags);
58
			    const unsigned int flags);
59
static void netsh_command (const struct argv *a, int n);
59
60
60
static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc);
61
static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc);
61
62
62
#endif
63
#endif
63
64
64
#ifdef TARGET_SOLARIS
65
#ifdef TARGET_SOLARIS
65
static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual);
66
static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual, bool unplumb_inet6);
66
#include <stropts.h>
67
#include <stropts.h>
67
#endif
68
#endif
68
69
Lines 129-158 Link Here
129
  return dev;
130
  return dev;
130
}
131
}
131
132
132
/*
133
 * Called by the open_tun function of OSes to check if we
134
 * explicitly support IPv6.
135
 *
136
 * In this context, explicit means that the OS expects us to
137
 * do something special to the tun socket in order to support
138
 * IPv6, i.e. it is not transparent.
139
 *
140
 * ipv6_explicitly_supported should be set to false if we don't
141
 * have any explicit IPv6 code in the tun device handler.
142
 *
143
 * If ipv6_explicitly_supported is true, then we have explicit
144
 * OS-specific tun dev code for handling IPv6.  If so, tt->ipv6
145
 * is set according to the --tun-ipv6 command line option.
146
 */
147
static void
148
ipv6_support (bool ipv6, bool ipv6_explicitly_supported, struct tuntap* tt)
149
{
150
  tt->ipv6 = false;
151
  if (ipv6_explicitly_supported)
152
    tt->ipv6 = ipv6;
153
  else if (ipv6)
154
    msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
155
}
156
133
157
/* --ifconfig-nowarn disables some options sanity checking */
134
/* --ifconfig-nowarn disables some options sanity checking */
158
static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)";
135
static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)";
Lines 423-428 Link Here
423
	  int topology,          /* one of the TOP_x values */
400
	  int topology,          /* one of the TOP_x values */
424
	  const char *ifconfig_local_parm,          /* --ifconfig parm 1 */
401
	  const char *ifconfig_local_parm,          /* --ifconfig parm 1 */
425
	  const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
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 */
426
	  in_addr_t local_public,
405
	  in_addr_t local_public,
427
	  in_addr_t remote_public,
406
	  in_addr_t remote_public,
428
	  const bool strict_warn,
407
	  const bool strict_warn,
Lines 537-542 Link Here
537
516
538
      tt->did_ifconfig_setup = true;
517
      tt->did_ifconfig_setup = true;
539
    }
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
540
  gc_free (&gc);
553
  gc_free (&gc);
541
  return tt;
554
  return tt;
542
}
555
}
Lines 559-564 Link Here
559
#endif
572
#endif
560
}
573
}
561
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
595
void delete_route_connected_v6_net(struct tuntap * tt,
596
	                           const struct env_set *es)
597
{
598
    struct route_ipv6 r6;
599
600
    r6.defined = true;
601
    r6.network = tt->local_ipv6;
602
    r6.netbits = tt->netbits_ipv6;
603
    r6.gateway = tt->local_ipv6;
604
    delete_route_ipv6 (&r6, tt, 0, es);
605
}
606
#endif
607
608
562
/* execute the ifconfig command through the shell */
609
/* execute the ifconfig command through the shell */
563
void
610
void
564
do_ifconfig (struct tuntap *tt,
611
do_ifconfig (struct tuntap *tt,
Lines 574-583 Link Here
574
      const char *ifconfig_local = NULL;
621
      const char *ifconfig_local = NULL;
575
      const char *ifconfig_remote_netmask = NULL;
622
      const char *ifconfig_remote_netmask = NULL;
576
      const char *ifconfig_broadcast = NULL;
623
      const char *ifconfig_broadcast = NULL;
624
      const char *ifconfig_ipv6_local = NULL;
625
      const char *ifconfig_ipv6_remote = NULL;
626
      bool do_ipv6 = false;
577
      struct argv argv;
627
      struct argv argv;
578
628
579
      argv_init (&argv);
629
      argv_init (&argv);
580
630
631
      msg( M_INFO, "do_ifconfig, tt->ipv6=%d, tt->did_ifconfig_ipv6_setup=%d",
632
	           tt->ipv6, tt->did_ifconfig_ipv6_setup );
633
581
      /*
634
      /*
582
       * We only handle TUN/TAP devices here, not --dev null devices.
635
       * We only handle TUN/TAP devices here, not --dev null devices.
583
       */
636
       */
Lines 589-594 Link Here
589
      ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
642
      ifconfig_local = print_in_addr_t (tt->local, 0, &gc);
590
      ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
643
      ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc);
591
644
645
      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
646
        {
647
	  ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
648
	  ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc);
649
	  do_ipv6 = true;
650
	}
651
592
      /*
652
      /*
593
       * If TAP-style device, generate broadcast address.
653
       * If TAP-style device, generate broadcast address.
594
       */
654
       */
Lines 647-653 Link Here
647
		  argv_msg (M_INFO, &argv);
707
		  argv_msg (M_INFO, &argv);
648
		  openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed");
708
		  openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed");
649
	}
709
	}
650
	tt->did_ifconfig = true;
710
      if ( do_ipv6 )
711
	{
712
	  argv_printf( &argv,
713
		      "%s -6 addr add %s/%d dev %s",
714
		      iproute_path,
715
		      ifconfig_ipv6_local,
716
		      tt->netbits_ipv6,
717
		      actual
718
		      );
719
	  argv_msg (M_INFO, &argv);
720
	  openvpn_execve_check (&argv, es, S_FATAL, "Linux ip -6 addr add failed");
721
	}
722
      tt->did_ifconfig = true;
651
#else
723
#else
652
      if (tun)
724
      if (tun)
653
	argv_printf (&argv,
725
	argv_printf (&argv,
Lines 670-675 Link Here
670
			  );
742
			  );
671
      argv_msg (M_INFO, &argv);
743
      argv_msg (M_INFO, &argv);
672
      openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig failed");
744
      openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig failed");
745
      if ( do_ipv6 )
746
	{
747
	  argv_printf (&argv,
748
			  "%s %s inet6 add %s/%d",
749
			  IFCONFIG_PATH,
750
			  actual,
751
			  ifconfig_ipv6_local,
752
			  tt->netbits_ipv6
753
			  );
754
	  argv_msg (M_INFO, &argv);
755
	  openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig inet6 failed");
756
	}
673
      tt->did_ifconfig = true;
757
      tt->did_ifconfig = true;
674
758
675
#endif /*CONFIG_FEATURE_IPROUTE*/
759
#endif /*CONFIG_FEATURE_IPROUTE*/
Lines 693-699 Link Here
693
777
694
	  argv_msg (M_INFO, &argv);
778
	  argv_msg (M_INFO, &argv);
695
	  if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-1 failed"))
779
	  if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-1 failed"))
696
	    solaris_error_close (tt, es, actual);
780
	    solaris_error_close (tt, es, actual, false);
697
781
698
	  argv_printf (&argv,
782
	  argv_printf (&argv,
699
			    "%s %s netmask 255.255.255.255",
783
			    "%s %s netmask 255.255.255.255",
Lines 725-731 Link Here
725
809
726
      argv_msg (M_INFO, &argv);
810
      argv_msg (M_INFO, &argv);
727
      if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed"))
811
      if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed"))
728
	solaris_error_close (tt, es, actual);
812
	solaris_error_close (tt, es, actual, false);
813
814
      if ( do_ipv6 )
815
        {
816
 	  argv_printf (&argv, "%s %s inet6 unplumb",
817
			    IFCONFIG_PATH, actual );
818
	  argv_msg (M_INFO, &argv);
819
	  openvpn_execve_check (&argv, es, 0, NULL);
820
821
	  if ( tt->type == DEV_TYPE_TUN )
822
	   {
823
	      argv_printf (&argv,
824
			    "%s %s inet6 plumb %s/%d %s up",
825
			    IFCONFIG_PATH,
826
			    actual,
827
			    ifconfig_ipv6_local,
828
			    tt->netbits_ipv6,
829
			    ifconfig_ipv6_remote
830
			    );
831
	    }
832
	  else						/* tap mode */
833
	    {
834
	      /* base IPv6 tap interface needs to be brought up first
835
	       */
836
	      argv_printf (&argv, "%s %s inet6 plumb up",
837
			    IFCONFIG_PATH, actual );
838
	      argv_msg (M_INFO, &argv);
839
	      if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed"))
840
		solaris_error_close (tt, es, actual, true);
841
842
	      /* we might need to do "ifconfig %s inet6 auto-dhcp drop"
843
	       * after the system has noticed the interface and fired up
844
	       * the DHCPv6 client - but this takes quite a while, and the 
845
	       * server will ignore the DHCPv6 packets anyway.  So we don't.
846
	       */
847
848
	      /* static IPv6 addresses need to go to a subinterface (tap0:1)
849
	       */
850
	      argv_printf (&argv,
851
			    "%s %s inet6 addif %s/%d up",
852
			    IFCONFIG_PATH, actual,
853
			    ifconfig_ipv6_local, tt->netbits_ipv6 );
854
	    }
855
	  argv_msg (M_INFO, &argv);
856
	  if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 failed"))
857
	    solaris_error_close (tt, es, actual, true);
858
        }
729
859
730
      if (!tun && tt->topology == TOP_SUBNET)
860
      if (!tun && tt->topology == TOP_SUBNET)
731
	{
861
	{
Lines 787-796 Link Here
787
			  );
917
			  );
788
      argv_msg (M_INFO, &argv);
918
      argv_msg (M_INFO, &argv);
789
      openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig failed");
919
      openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig failed");
920
      if ( do_ipv6 )
921
	{
922
	  argv_printf (&argv,
923
			  "%s %s inet6 %s/%d",
924
			  IFCONFIG_PATH,
925
			  actual,
926
			  ifconfig_ipv6_local,
927
			  tt->netbits_ipv6
928
			  );
929
	  argv_msg (M_INFO, &argv);
930
	  openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed");
931
932
	  /* and, hooray, we explicitely need to add a route... */
933
	  add_route_connected_v6_net(tt, es);
934
	}
790
      tt->did_ifconfig = true;
935
      tt->did_ifconfig = true;
791
936
792
#elif defined(TARGET_NETBSD)
937
#elif defined(TARGET_NETBSD)
793
938
939
/* whether or not NetBSD can do IPv6 can be seen by the availability of
940
 * the TUNSIFHEAD ioctl() - see next TARGET_NETBSD block for more details
941
 */
942
#ifdef TUNSIFHEAD
943
# define NETBSD_MULTI_AF
944
#endif
945
946
      /* as on OpenBSD and Darwin, destroy and re-create tun<x> interface
947
       */
948
      argv_printf (&argv, "%s %s destroy", IFCONFIG_PATH, actual );
949
      argv_msg (M_INFO, &argv);
950
      openvpn_execve_check (&argv, es, 0, "NetBSD ifconfig destroy failed");
951
952
      argv_printf (&argv, "%s %s create", IFCONFIG_PATH, actual );
953
      argv_msg (M_INFO, &argv);
954
      openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig create failed");
955
794
      if (tun)
956
      if (tun)
795
	argv_printf (&argv,
957
	argv_printf (&argv,
796
			  "%s %s %s %s mtu %d netmask 255.255.255.255 up",
958
			  "%s %s %s %s mtu %d netmask 255.255.255.255 up",
Lines 817-822 Link Here
817
			  );
979
			  );
818
      argv_msg (M_INFO, &argv);
980
      argv_msg (M_INFO, &argv);
819
      openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig failed");
981
      openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig failed");
982
983
      if ( do_ipv6 )
984
	{
985
#ifdef NETBSD_MULTI_AF
986
	  argv_printf (&argv,
987
			  "%s %s inet6 %s/%d",
988
			  IFCONFIG_PATH,
989
			  actual,
990
			  ifconfig_ipv6_local,
991
			  tt->netbits_ipv6
992
			  );
993
	  argv_msg (M_INFO, &argv);
994
	  openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed");
995
996
	  /* and, hooray, we explicitely need to add a route... */
997
	  add_route_connected_v6_net(tt, es);
998
#else
999
	  msg( M_INFO, "no IPv6 support for tun interfaces on NetBSD before 4.0 (if your system is newer, recompile openvpn)" );
1000
	  tt->ipv6 = false;
1001
#endif
1002
	}
820
      tt->did_ifconfig = true;
1003
      tt->did_ifconfig = true;
821
1004
822
#elif defined(TARGET_DARWIN)
1005
#elif defined(TARGET_DARWIN)
Lines 882-887 Link Here
882
	  add_route (&r, tt, 0, es);
1065
	  add_route (&r, tt, 0, es);
883
	}
1066
	}
884
1067
1068
      if ( do_ipv6 )
1069
	{
1070
          argv_printf (&argv,
1071
                              "%s %s inet6 %s/%d",
1072
                              IFCONFIG_PATH,
1073
                              actual,
1074
                              ifconfig_ipv6_local,
1075
                              tt->netbits_ipv6
1076
                              );
1077
	  argv_msg (M_INFO, &argv);
1078
	  openvpn_execve_check (&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed");
1079
1080
	  /* and, hooray, we explicitely need to add a route... */
1081
	  add_route_connected_v6_net(tt, es);
1082
	}
1083
885
#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
1084
#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY)
886
1085
887
      /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
1086
      /* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */
Lines 920-925 Link Here
920
          add_route (&r, tt, 0, es);
1119
          add_route (&r, tt, 0, es);
921
        }
1120
        }
922
1121
1122
      if ( do_ipv6 )
1123
	{
1124
          argv_printf (&argv,
1125
                              "%s %s inet6 %s/%d",
1126
                              IFCONFIG_PATH,
1127
                              actual,
1128
                              ifconfig_ipv6_local,
1129
                              tt->netbits_ipv6
1130
                              );
1131
	  argv_msg (M_INFO, &argv);
1132
	  openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed");
1133
	}
1134
923
#elif defined (WIN32)
1135
#elif defined (WIN32)
924
      {
1136
      {
925
	/*
1137
	/*
Lines 959-964 Link Here
959
	tt->did_ifconfig = true;
1171
	tt->did_ifconfig = true;
960
      }
1172
      }
961
1173
1174
    /* IPv6 always uses "netsh" interface */
1175
    if ( do_ipv6 )
1176
      {
1177
	char * saved_actual;
1178
1179
	if (!strcmp (actual, "NULL"))
1180
	  msg (M_FATAL, "Error: When using --tun-ipv6, if you have more than one TAP-Win32 adapter, you must also specify --dev-node");
1181
1182
	/* example: netsh interface ipv6 set address MyTap 2001:608:8003::d store=active */
1183
	argv_printf (&argv,
1184
		    "%s%sc interface ipv6 set address %s %s store=active",
1185
		     get_win_sys_path(),
1186
		     NETSH_PATH_SUFFIX,
1187
		     actual,
1188
		     ifconfig_ipv6_local );
1189
1190
	netsh_command (&argv, 4);
1191
1192
	/* explicit route needed */
1193
	/* on windows, OpenVPN does ifconfig first, open_tun later, so
1194
	 * tt->actual_name might not yet be initialized, but routing code
1195
	 * needs to know interface name - point to "actual", restore later
1196
	 */
1197
	saved_actual = tt->actual_name;
1198
	tt->actual_name = (char*) actual;
1199
	add_route_connected_v6_net(tt, es);
1200
	tt->actual_name = saved_actual;
1201
      }
962
#else
1202
#else
963
      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.");
1203
      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.");
964
#endif
1204
#endif
Lines 991-1004 Link Here
991
#ifndef WIN32
1231
#ifndef WIN32
992
static void
1232
static void
993
open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
1233
open_tun_generic (const char *dev, const char *dev_type, const char *dev_node,
994
		  bool ipv6, bool ipv6_explicitly_supported, bool dynamic,
1234
		  bool ipv6_explicitly_supported, bool dynamic,
995
		  struct tuntap *tt)
1235
		  struct tuntap *tt)
996
{
1236
{
997
  char tunname[256];
1237
  char tunname[256];
998
  char dynamic_name[256];
1238
  char dynamic_name[256];
999
  bool dynamic_opened = false;
1239
  bool dynamic_opened = false;
1000
1240
1001
  ipv6_support (ipv6, ipv6_explicitly_supported, tt);
1241
1242
  if ( tt->ipv6 && ! ipv6_explicitly_supported )
1243
    msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
1002
1244
1003
  if (tt->type == DEV_TYPE_NULL)
1245
  if (tt->type == DEV_TYPE_NULL)
1004
    {
1246
    {
Lines 1094-1109 Link Here
1094
#if !PEDANTIC
1336
#if !PEDANTIC
1095
1337
1096
void
1338
void
1097
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1339
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1098
{
1340
{
1099
  struct ifreq ifr;
1341
  struct ifreq ifr;
1100
1342
1101
  /*
1343
  /* warn if a very old linux version is used & --tun-ipv6 set
1102
   * Set tt->ipv6 to true if
1103
   * (a) we have the capability of supporting --tun-ipv6, and
1104
   * (b) --tun-ipv6 was specified.
1105
   */
1344
   */
1106
  ipv6_support (ipv6, LINUX_IPV6, tt);
1345
#if LINUX_IPV6 == 0
1346
  if ( tt->ipv6 )
1347
    msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS");
1348
#endif
1107
1349
1108
  /*
1350
  /*
1109
   * We handle --dev null specially, we do not open /dev/null for this.
1351
   * We handle --dev null specially, we do not open /dev/null for this.
Lines 1212-1218 Link Here
1212
#else
1454
#else
1213
1455
1214
void
1456
void
1215
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1457
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1216
{
1458
{
1217
  ASSERT (0);
1459
  ASSERT (0);
1218
}
1460
}
Lines 1222-1230 Link Here
1222
#else
1464
#else
1223
1465
1224
void
1466
void
1225
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1467
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1226
{
1468
{
1227
  open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
1469
  open_tun_generic (dev, dev_type, dev_node, false, true, tt);
1228
}
1470
}
1229
1471
1230
#endif /* HAVE_LINUX_IF_TUN_H */
1472
#endif /* HAVE_LINUX_IF_TUN_H */
Lines 1244-1250 Link Here
1244
#endif
1486
#endif
1245
1487
1246
void
1488
void
1247
tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options)
1489
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)
1248
{
1490
{
1249
  struct tuntap *tt;
1491
  struct tuntap *tt;
1250
1492
Lines 1252-1258 Link Here
1252
  clear_tuntap (tt);
1494
  clear_tuntap (tt);
1253
  tt->type = dev_type_enum (dev, dev_type);
1495
  tt->type = dev_type_enum (dev, dev_type);
1254
  tt->options = *options;
1496
  tt->options = *options;
1255
  open_tun (dev, dev_type, dev_node, ipv6, tt);
1497
  open_tun (dev, dev_type, dev_node, tt);
1256
  if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
1498
  if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0)
1257
    msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
1499
    msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
1258
  if (username != NULL)
1500
  if (username != NULL)
Lines 1395-1401 Link Here
1395
#endif
1637
#endif
1396
1638
1397
void
1639
void
1398
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1640
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1399
{
1641
{
1400
  int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1;
1642
  int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1;
1401
  struct lifreq ifr;
1643
  struct lifreq ifr;
Lines 1406-1413 Link Here
1406
  bool is_tun;
1648
  bool is_tun;
1407
  struct strioctl  strioc_if, strioc_ppa;
1649
  struct strioctl  strioc_if, strioc_ppa;
1408
1650
1409
  ipv6_support (ipv6, true, tt);
1651
  /* improved generic TUN/TAP driver from
1410
  memset(&ifr, 0x0, sizeof(ifr));
1652
   * http://www.whiteboard.ne.jp/~admin2/tuntap/
1653
   * has IPv6 support
1654
   */
1655
  CLEAR(ifr);
1411
1656
1412
  if (tt->type == DEV_TYPE_NULL)
1657
  if (tt->type == DEV_TYPE_NULL)
1413
    {
1658
    {
Lines 1561-1566 Link Here
1561
{
1806
{
1562
  if (tt)
1807
  if (tt)
1563
    {
1808
    {
1809
      /* IPv6 interfaces need to be 'manually' de-configured */
1810
      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
1811
	{
1812
	  struct argv argv;
1813
	  argv_init (&argv);
1814
	  argv_printf( &argv, "%s %s inet6 unplumb",
1815
		       IFCONFIG_PATH, tt->actual_name );
1816
	  argv_msg (M_INFO, &argv);
1817
	  openvpn_execve_check (&argv, NULL, 0, "Solaris ifconfig inet6 unplumb failed");
1818
	  argv_reset (&argv);
1819
	}
1820
1564
      if (tt->ip_fd >= 0)
1821
      if (tt->ip_fd >= 0)
1565
	{
1822
	{
1566
          struct lifreq ifr;
1823
          struct lifreq ifr;
Lines 1613-1623 Link Here
1613
}
1870
}
1614
1871
1615
static void
1872
static void
1616
solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual)
1873
solaris_error_close (struct tuntap *tt, const struct env_set *es, 
1874
                     const char *actual, bool unplumb_inet6 )
1617
{
1875
{
1618
  struct argv argv;
1876
  struct argv argv;
1619
  argv_init (&argv);
1877
  argv_init (&argv);
1620
1878
1879
  if (unplumb_inet6)
1880
    {
1881
      argv_printf( &argv, "%s %s inet6 unplumb",
1882
		   IFCONFIG_PATH, actual );
1883
      argv_msg (M_INFO, &argv);
1884
      openvpn_execve_check (&argv, es, 0, "Solaris ifconfig inet6 unplumb failed");
1885
    }
1886
1621
  argv_printf (&argv,
1887
  argv_printf (&argv,
1622
		    "%s %s unplumb",
1888
		    "%s %s unplumb",
1623
		    IFCONFIG_PATH,
1889
		    IFCONFIG_PATH,
Lines 1674-1682 Link Here
1674
 */
1940
 */
1675
1941
1676
void
1942
void
1677
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
1943
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1678
{
1944
{
1679
  open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
1945
  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
1680
1946
1681
  /* Enable multicast on the interface */
1947
  /* Enable multicast on the interface */
1682
  if (tt->fd >= 0)
1948
  if (tt->fd >= 0)
Lines 1697-1708 Link Here
1697
    }
1963
    }
1698
}
1964
}
1699
1965
1966
/* the current way OpenVPN handles tun devices on OpenBSD leads to
1967
 * lingering tunX interfaces after close -> for a full cleanup, they
1968
 * need to be explicitely destroyed
1969
 */
1970
1700
void
1971
void
1701
close_tun (struct tuntap* tt)
1972
close_tun (struct tuntap* tt)
1702
{
1973
{
1703
  if (tt)
1974
  if (tt)
1704
    {
1975
    {
1976
      struct gc_arena gc = gc_new ();
1977
      struct argv argv;
1978
1979
      /* setup command, close tun dev (clears tt->actual_name!), run command
1980
       */
1981
1982
      argv_init (&argv);
1983
      argv_printf (&argv, "%s %s destroy",
1984
                          IFCONFIG_PATH, tt->actual_name);
1985
1705
      close_tun_generic (tt);
1986
      close_tun_generic (tt);
1987
1988
      argv_msg (M_INFO, &argv);
1989
      openvpn_execve_check (&argv, NULL, 0, "OpenBSD 'destroy tun interface' failed (non-critical)");
1990
1706
      free (tt);
1991
      free (tt);
1707
    }
1992
    }
1708
}
1993
}
Lines 1765-1797 Link Here
1765
#elif defined(TARGET_NETBSD)
2050
#elif defined(TARGET_NETBSD)
1766
2051
1767
/*
2052
/*
1768
 * NetBSD does not support IPv6 on tun out of the box,
2053
 * NetBSD before 4.0 does not support IPv6 on tun out of the box,
1769
 * but there exists a patch. When this patch is applied,
2054
 * but there exists a patch (sys/net/if_tun.c, 1.79->1.80, see PR 32944).
1770
 * only two things are left to openvpn:
2055
 *
1771
 * 1. Activate multicasting (this has already been done
2056
 * NetBSD 4.0 and up do, but we need to put the tun interface into
1772
 *    before by the kernel, but we make sure that nobody
2057
 * "multi_af" mode, which will prepend the address family to all packets
1773
 *    has deactivated multicasting inbetween.
2058
 * (same as OpenBSD and FreeBSD).  If this is not enabled, the kernel
1774
 * 2. Deactivate "link layer mode" (otherwise NetBSD 
2059
 * silently drops all IPv6 packets on output and gets confused on input.
1775
 *    prepends the address family to the packet, and we
2060
 *
1776
 *    would run into the same trouble as with OpenBSD.
2061
 * On earlier versions, multi_af is not available at all, so we have
2062
 * two different NetBSD code variants here :-(
2063
 *
1777
 */
2064
 */
1778
2065
1779
void
2066
void
1780
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
2067
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1781
{
2068
{
1782
    open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
2069
#ifdef NETBSD_MULTI_AF
2070
    open_tun_generic (dev, dev_type, dev_node, true, true, tt);
2071
#else
2072
    open_tun_generic (dev, dev_type, dev_node, false, true, tt);
2073
#endif
2074
1783
    if (tt->fd >= 0)
2075
    if (tt->fd >= 0)
1784
      {
2076
      {
1785
        int i = IFF_POINTOPOINT|IFF_MULTICAST;
2077
        int i = IFF_POINTOPOINT|IFF_MULTICAST;
1786
        ioctl (tt->fd, TUNSIFMODE, &i);  /* multicast on */
2078
        ioctl (tt->fd, TUNSIFMODE, &i);  /* multicast on */
1787
        i = 0;
2079
        i = 0;
1788
        ioctl (tt->fd, TUNSLMODE, &i);   /* link layer mode off */
2080
        ioctl (tt->fd, TUNSLMODE, &i);   /* link layer mode off */
2081
2082
#ifdef NETBSD_MULTI_AF
2083
        i = 1;
2084
        if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) 	/* multi-af mode on */
2085
	  {
2086
	    msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno));
2087
	  }
2088
#endif
1789
      }
2089
      }
1790
}
2090
}
1791
2091
1792
void
2092
void
1793
close_tun (struct tuntap *tt)
2093
close_tun (struct tuntap *tt)
1794
{
2094
{
2095
  /* TODO: we really should cleanup non-persistant tunX with 
2096
   * "ifconfig tunX destroy" here...
2097
   */
1795
  if (tt)
2098
  if (tt)
1796
    {
2099
    {
1797
      close_tun_generic (tt);
2100
      close_tun_generic (tt);
Lines 1799-1804 Link Here
1799
    }
2102
    }
1800
}
2103
}
1801
2104
2105
#ifdef NETBSD_MULTI_AF
2106
2107
static inline int
2108
netbsd_modify_read_write_return (int len)
2109
{
2110
  if (len > 0)
2111
    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
2112
  else
2113
    return len;
2114
}
2115
2116
int
2117
write_tun (struct tuntap* tt, uint8_t *buf, int len)
2118
{
2119
  if (tt->type == DEV_TYPE_TUN)
2120
    {
2121
      u_int32_t type;
2122
      struct iovec iv[2];
2123
      struct openvpn_iphdr *iph;
2124
2125
      iph = (struct openvpn_iphdr *) buf;
2126
2127
      if (tt->ipv6 && OPENVPN_IPH_GET_VER(iph->version_len) == 6)
2128
        type = htonl (AF_INET6);
2129
      else 
2130
        type = htonl (AF_INET);
2131
2132
      iv[0].iov_base = (char *)&type;
2133
      iv[0].iov_len = sizeof (type);
2134
      iv[1].iov_base = buf;
2135
      iv[1].iov_len = len;
2136
2137
      return netbsd_modify_read_write_return (writev (tt->fd, iv, 2));
2138
    }
2139
  else
2140
    return write (tt->fd, buf, len);
2141
}
2142
2143
int
2144
read_tun (struct tuntap* tt, uint8_t *buf, int len)
2145
{
2146
  if (tt->type == DEV_TYPE_TUN)
2147
    {
2148
      u_int32_t type;
2149
      struct iovec iv[2];
2150
2151
      iv[0].iov_base = (char *)&type;
2152
      iv[0].iov_len = sizeof (type);
2153
      iv[1].iov_base = buf;
2154
      iv[1].iov_len = len;
2155
2156
      return netbsd_modify_read_write_return (readv (tt->fd, iv, 2));
2157
    }
2158
  else
2159
    return read (tt->fd, buf, len);
2160
}
2161
2162
#else	/* not NETBSD_MULTI_AF -> older code, IPv4 only */
2163
1802
int
2164
int
1803
write_tun (struct tuntap* tt, uint8_t *buf, int len)
2165
write_tun (struct tuntap* tt, uint8_t *buf, int len)
1804
{
2166
{
Lines 1810-1815 Link Here
1810
{
2172
{
1811
    return read (tt->fd, buf, len);
2173
    return read (tt->fd, buf, len);
1812
}
2174
}
2175
#endif	/* NETBSD_MULTI_AF */
1813
2176
1814
#elif defined(TARGET_FREEBSD)
2177
#elif defined(TARGET_FREEBSD)
1815
2178
Lines 1823-1831 Link Here
1823
}
2186
}
1824
2187
1825
void
2188
void
1826
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
2189
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1827
{
2190
{
1828
  open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
2191
  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
1829
2192
1830
  if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
2193
  if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN)
1831
    {
2194
    {
Lines 1911-1919 Link Here
1911
}
2274
}
1912
2275
1913
void
2276
void
1914
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
2277
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1915
{
2278
{
1916
  open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt);
2279
  open_tun_generic (dev, dev_type, dev_node, true, true, tt);
1917
2280
1918
  if (tt->fd >= 0)
2281
  if (tt->fd >= 0)
1919
    {
2282
    {
Lines 1982-1987 Link Here
1982
    return read (tt->fd, buf, len);
2345
    return read (tt->fd, buf, len);
1983
}
2346
}
1984
2347
2348
#elif defined(TARGET_DARWIN)
2349
2350
/* Darwin (MacOS X) is mostly "just use the generic stuff", but there
2351
 * is always one caveat...:
2352
 *
2353
 * If IPv6 is configured, and the tun device is closed, the IPv6 address
2354
 * configured to the tun interface changes to a lingering /128 route
2355
 * pointing to lo0.  Need to unconfigure...  (observed on 10.5)
2356
 */
2357
2358
void
2359
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
2360
{
2361
  open_tun_generic (dev, dev_type, dev_node, false, true, tt);
2362
}
2363
2364
void
2365
close_tun (struct tuntap* tt)
2366
{
2367
  if (tt)
2368
    {
2369
      struct gc_arena gc = gc_new ();
2370
      struct argv argv;
2371
      argv_init (&argv);
2372
2373
      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
2374
	{
2375
	  const char * ifconfig_ipv6_local =
2376
				print_in6_addr (tt->local_ipv6, 0, &gc);
2377
2378
          argv_printf (&argv, "%s delete -inet6 %s",
2379
                              ROUTE_PATH, ifconfig_ipv6_local );
2380
	  argv_msg (M_INFO, &argv);
2381
	  openvpn_execve_check (&argv, NULL, 0, "MacOS X 'remove inet6 route' failed (non-critical)");
2382
	}
2383
2384
      close_tun_generic (tt);
2385
      free (tt);
2386
      argv_reset (&argv);
2387
      gc_free (&gc);
2388
    }
2389
}
2390
2391
int
2392
write_tun (struct tuntap* tt, uint8_t *buf, int len)
2393
{
2394
  return write (tt->fd, buf, len);
2395
}
2396
2397
int
2398
read_tun (struct tuntap* tt, uint8_t *buf, int len)
2399
{
2400
  return read (tt->fd, buf, len);
2401
}
2402
1985
#elif defined(WIN32)
2403
#elif defined(WIN32)
1986
2404
1987
int
2405
int
Lines 3967-3973 Link Here
3967
}
4385
}
3968
4386
3969
void
4387
void
3970
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
4388
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
3971
{
4389
{
3972
  struct gc_arena gc = gc_new ();
4390
  struct gc_arena gc = gc_new ();
3973
  char device_path[256];
4391
  char device_path[256];
Lines 3978-3984 Link Here
3978
4396
3979
  /*netcmd_semaphore_lock ();*/
4397
  /*netcmd_semaphore_lock ();*/
3980
4398
3981
  ipv6_support (ipv6, false, tt);
4399
  msg( M_INFO, "open_tun, tt->ipv6=%d", tt->ipv6 );
3982
4400
3983
  if (tt->type == DEV_TYPE_NULL)
4401
  if (tt->type == DEV_TYPE_NULL)
3984
    {
4402
    {
Lines 4101-4106 Link Here
4101
	   TAP_WIN32_MIN_MAJOR,
4519
	   TAP_WIN32_MIN_MAJOR,
4102
	   TAP_WIN32_MIN_MINOR);
4520
	   TAP_WIN32_MIN_MINOR);
4103
4521
4522
    /* usage of numeric constants is ugly, but this is really tied to
4523
     * *this* version of the driver
4524
     */
4525
    if ( tt->ipv6 && tt->type == DEV_TYPE_TUN &&
4526
         info[0] == 9 && info[1] < 8)
4527
      {
4528
       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] );
4529
       tt->ipv6 = false;
4530
      }
4531
4104
    /* tap driver 9.8 (2.2.0 and 2.2.1 release) is buggy
4532
    /* tap driver 9.8 (2.2.0 and 2.2.1 release) is buggy
4105
     */
4533
     */
4106
    if ( tt->type == DEV_TYPE_TUN &&
4534
    if ( tt->type == DEV_TYPE_TUN &&
Lines 4432-4437 Link Here
4432
4860
4433
  if (tt)
4861
  if (tt)
4434
    {
4862
    {
4863
      if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup )
4864
        {
4865
	  struct argv argv;
4866
	  argv_init (&argv);
4867
4868
	  /* remove route pointing to interface */
4869
	  delete_route_connected_v6_net(tt, NULL);
4870
4871
	  /* netsh interface ipv6 delete address \"%s\" %s */
4872
	  const char * ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc);
4873
	  argv_printf (&argv,
4874
		    "%s%sc interface ipv6 delete address %s %s",
4875
		     get_win_sys_path(),
4876
		     NETSH_PATH_SUFFIX,
4877
		     tt->actual_name,
4878
		     ifconfig_ipv6_local );
4879
4880
	  netsh_command (&argv, 1);
4881
          argv_reset (&argv);
4882
	}
4435
#if 1
4883
#if 1
4436
      if (tt->ipapi_context_defined)
4884
      if (tt->ipapi_context_defined)
4437
	{
4885
	{
Lines 4535-4543 Link Here
4535
#else /* generic */
4983
#else /* generic */
4536
4984
4537
void
4985
void
4538
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt)
4986
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
4539
{
4987
{
4540
  open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt);
4988
  open_tun_generic (dev, dev_type, dev_node, false, true, tt);
4541
}
4989
}
4542
4990
4543
void
4991
void
(-)openvpn-2.2.2_unpatched//tun.h (-2 / +9 lines)
Lines 130-135 Link Here
130
  int topology; /* one of the TOP_x values */
130
  int topology; /* one of the TOP_x values */
131
131
132
  bool did_ifconfig_setup;
132
  bool did_ifconfig_setup;
133
  bool did_ifconfig_ipv6_setup;
133
  bool did_ifconfig;
134
  bool did_ifconfig;
134
135
135
  bool ipv6;
136
  bool ipv6;
Lines 146-151 Link Here
146
  in_addr_t remote_netmask;
147
  in_addr_t remote_netmask;
147
  in_addr_t broadcast;
148
  in_addr_t broadcast;
148
149
150
  struct in6_addr local_ipv6;
151
  struct in6_addr remote_ipv6;
152
  int netbits_ipv6;
153
149
#ifdef WIN32
154
#ifdef WIN32
150
  HANDLE hand;
155
  HANDLE hand;
151
  struct overlapped_io reads;
156
  struct overlapped_io reads;
Lines 197-203 Link Here
197
void clear_tuntap (struct tuntap *tuntap);
202
void clear_tuntap (struct tuntap *tuntap);
198
203
199
void open_tun (const char *dev, const char *dev_type, const char *dev_node,
204
void open_tun (const char *dev, const char *dev_type, const char *dev_node,
200
	       bool ipv6, struct tuntap *tt);
205
	       struct tuntap *tt);
201
206
202
void close_tun (struct tuntap *tt);
207
void close_tun (struct tuntap *tt);
203
208
Lines 206-212 Link Here
206
int read_tun (struct tuntap* tt, uint8_t *buf, int len);
211
int read_tun (struct tuntap* tt, uint8_t *buf, int len);
207
212
208
void tuncfg (const char *dev, const char *dev_type, const char *dev_node,
213
void tuncfg (const char *dev, const char *dev_type, const char *dev_node,
209
	     bool ipv6, int persist_mode, const char *username,
214
	     int persist_mode, const char *username,
210
	     const char *groupname, const struct tuntap_options *options);
215
	     const char *groupname, const struct tuntap_options *options);
211
216
212
const char *guess_tuntap_dev (const char *dev,
217
const char *guess_tuntap_dev (const char *dev,
Lines 219-224 Link Here
219
			 int topology,          /* one of the TOP_x values */
224
			 int topology,          /* one of the TOP_x values */
220
			 const char *ifconfig_local_parm,          /* --ifconfig parm 1 */
225
			 const char *ifconfig_local_parm,          /* --ifconfig parm 1 */
221
			 const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
226
			 const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
227
			 const char *ifconfig_ipv6_local_parm,     /* --ifconfig parm 1 / IPv6 */
228
			 const char *ifconfig_ipv6_remote_parm,    /* --ifconfig parm 2 / IPv6 */
222
			 in_addr_t local_public,
229
			 in_addr_t local_public,
223
			 in_addr_t remote_public,
230
			 in_addr_t remote_public,
224
			 const bool strict_warn,
231
			 const bool strict_warn,
(-)openvpn-2.2.2_unpatched//win32.c (+16 lines)
Lines 874-889 Link Here
874
static char *
874
static char *
875
env_block (const struct env_set *es)
875
env_block (const struct env_set *es)
876
{
876
{
877
  char * force_path = "PATH=C:\\Windows\\System32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem";
878
877
  if (es)
879
  if (es)
878
    {
880
    {
879
      struct env_item *e;
881
      struct env_item *e;
880
      char *ret;
882
      char *ret;
881
      char *p;
883
      char *p;
882
      size_t nchars = 1;
884
      size_t nchars = 1;
885
      bool path_seen = false;
883
      
886
      
884
      for (e = es->list; e != NULL; e = e->next)
887
      for (e = es->list; e != NULL; e = e->next)
885
	nchars += strlen (e->string) + 1;
888
	nchars += strlen (e->string) + 1;
886
889
890
      nchars += strlen(force_path)+1;
891
887
      ret = (char *) malloc (nchars);
892
      ret = (char *) malloc (nchars);
888
      check_malloc_return (ret);
893
      check_malloc_return (ret);
889
894
Lines 895-901 Link Here
895
	      strcpy (p, e->string);
900
	      strcpy (p, e->string);
896
	      p += strlen (e->string) + 1;
901
	      p += strlen (e->string) + 1;
897
	    }
902
	    }
903
	  if ( strncmp(e->string, "PATH=", 5 ) == 0 )
904
	    path_seen = true;
905
	}
906
907
      /* make sure PATH is set */
908
      if ( !path_seen )
909
	{
910
	  msg( M_INFO, "env_block: add %s", force_path );
911
	  strcpy( p, force_path );
912
	  p += strlen(force_path) + 1;
898
	}
913
	}
914
899
      *p = '\0';
915
      *p = '\0';
900
      return ret;
916
      return ret;
901
    }
917
    }
(-)openvpn-2.2.2_unpatched//win32.h (+2 lines)
Lines 269-274 Link Here
269
269
270
/* call self in a subprocess */
270
/* call self in a subprocess */
271
void fork_to_self (const char *cmdline);
271
void fork_to_self (const char *cmdline);
272
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
273
int inet_pton(int af, const char *src, void *st);
272
274
273
/* Find temporary directory */
275
/* Find temporary directory */
274
const char *win_get_tempdir();
276
const char *win_get_tempdir();

Return to bug 405937