vpnc-script 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. #!/bin/sh
  2. #
  3. # Originally part of vpnc source code:
  4. # © 2005-2012 Maurice Massar, Jörg Mayer, Antonio Borneo et al.
  5. # © 2009-2012 David Woodhouse <dwmw2@infradead.org>
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. #
  21. ################
  22. #
  23. # List of parameters passed through environment
  24. #* reason -- why this script was called, one of: pre-init connect disconnect reconnect
  25. #* VPNGATEWAY -- vpn gateway address (always present)
  26. #* TUNDEV -- tunnel device (always present)
  27. #* INTERNAL_IP4_ADDRESS -- address (always present)
  28. #* INTERNAL_IP4_MTU -- mtu (often unset)
  29. #* INTERNAL_IP4_NETMASK -- netmask (often unset)
  30. #* INTERNAL_IP4_NETMASKLEN -- netmask length (often unset)
  31. #* INTERNAL_IP4_NETADDR -- address of network (only present if netmask is set)
  32. #* INTERNAL_IP4_DNS -- list of dns servers
  33. #* INTERNAL_IP4_NBNS -- list of wins servers
  34. #* INTERNAL_IP6_ADDRESS -- IPv6 address
  35. #* INTERNAL_IP6_NETMASK -- IPv6 netmask
  36. #* INTERNAL_IP6_DNS -- IPv6 list of dns servers
  37. #* CISCO_DEF_DOMAIN -- default domain name
  38. #* CISCO_BANNER -- banner from server
  39. #* CISCO_SPLIT_INC -- number of networks in split-network-list
  40. #* CISCO_SPLIT_INC_%d_ADDR -- network address
  41. #* CISCO_SPLIT_INC_%d_MASK -- subnet mask (for example: 255.255.255.0)
  42. #* CISCO_SPLIT_INC_%d_MASKLEN -- subnet masklen (for example: 24)
  43. #* CISCO_SPLIT_INC_%d_PROTOCOL -- protocol (often just 0)
  44. #* CISCO_SPLIT_INC_%d_SPORT -- source port (often just 0)
  45. #* CISCO_SPLIT_INC_%d_DPORT -- destination port (often just 0)
  46. #* CISCO_IPV6_SPLIT_INC -- number of networks in IPv6 split-network-list
  47. #* CISCO_IPV6_SPLIT_INC_%d_ADDR -- IPv6 network address
  48. #* CISCO_IPV6_SPLIT_INC_$%d_MASKLEN -- IPv6 subnet masklen
  49. # FIXMEs:
  50. # Section A: route handling
  51. # 1) The 3 values CISCO_SPLIT_INC_%d_PROTOCOL/SPORT/DPORT are currently being ignored
  52. # In order to use them, we'll probably need os specific solutions
  53. # * Linux: iptables -t mangle -I PREROUTING <conditions> -j ROUTE --oif $TUNDEV
  54. # This would be an *alternative* to changing the routes (and thus 2) and 3)
  55. # shouldn't be relevant at all)
  56. # 2) There are two different functions to set routes: generic routes and the
  57. # default route. Why isn't the defaultroute handled via the generic route case?
  58. # 3) In the split tunnel case, all routes but the default route might get replaced
  59. # without getting restored later. We should explicitely check and save them just
  60. # like the defaultroute
  61. # 4) Replies to a dhcp-server should never be sent into the tunnel
  62. # Section B: Split DNS handling
  63. # 1) Maybe dnsmasq can do something like that
  64. # 2) Parse dns packets going out via tunnel and redirect them to original dns-server
  65. #env | sort
  66. #set -x
  67. # =========== script (variable) setup ====================================
  68. PATH=/sbin:/usr/sbin:$PATH
  69. OS="`uname -s`"
  70. HOOKS_DIR=/etc/vpnc
  71. DEFAULT_ROUTE_FILE=/var/run/vpnc/defaultroute
  72. RESOLV_CONF_BACKUP=/var/run/vpnc/resolv.conf-backup
  73. SCRIPTNAME=`basename $0`
  74. # some systems, eg. Darwin & FreeBSD, prune /var/run on boot
  75. if [ ! -d "/var/run/vpnc" ]; then
  76. mkdir -p /var/run/vpnc
  77. [ -x /sbin/restorecon ] && /sbin/restorecon /var/run/vpnc
  78. fi
  79. # stupid SunOS: no blubber in /usr/local/bin ... (on stdout)
  80. IPROUTE="`which ip 2> /dev/null | grep '^/'`"
  81. if ifconfig --help 2>&1 | grep BusyBox > /dev/null; then
  82. ifconfig_syntax_inet=""
  83. else
  84. ifconfig_syntax_inet="inet"
  85. fi
  86. if [ "$OS" = "Linux" ]; then
  87. ifconfig_syntax_ptp="pointopoint"
  88. route_syntax_gw="gw"
  89. route_syntax_del="del"
  90. route_syntax_netmask="netmask"
  91. else
  92. ifconfig_syntax_ptp=""
  93. route_syntax_gw=""
  94. route_syntax_del="delete"
  95. route_syntax_netmask="-netmask"
  96. fi
  97. if [ "$OS" = "SunOS" ]; then
  98. route_syntax_interface="-interface"
  99. ifconfig_syntax_ptpv6="$INTERNAL_IP6_ADDRESS"
  100. else
  101. route_syntax_interface=""
  102. ifconfig_syntax_ptpv6=""
  103. fi
  104. if [ -r /etc/openwrt_release ] && [ -n "$OPENWRT_INTERFACE" ]; then
  105. . /etc/functions.sh
  106. include /lib/network
  107. MODIFYRESOLVCONF=modify_resolvconf_openwrt
  108. RESTORERESOLVCONF=restore_resolvconf_openwrt
  109. elif [ -x /usr/bin/resolvconf ] && [ "$OS" != "FreeBSD" ]; then # Optional tool on Debian, Ubuntu, Gentoo - but not FreeBSD, it seems to work different
  110. MODIFYRESOLVCONF=modify_resolvconf_manager
  111. RESTORERESOLVCONF=restore_resolvconf_manager
  112. elif [ -x /sbin/netconfig ]; then # tool on Suse after 11.1
  113. MODIFYRESOLVCONF=modify_resolvconf_suse_netconfig
  114. RESTORERESOLVCONF=restore_resolvconf_suse_netconfig
  115. elif [ -x /sbin/modify_resolvconf ]; then # Mandatory tool on Suse earlier than 11.1
  116. MODIFYRESOLVCONF=modify_resolvconf_suse
  117. RESTORERESOLVCONF=restore_resolvconf_suse
  118. else # Generic for any OS
  119. MODIFYRESOLVCONF=modify_resolvconf_generic
  120. RESTORERESOLVCONF=restore_resolvconf_generic
  121. fi
  122. # =========== script hooks =================================================
  123. run_hooks() {
  124. HOOK="$1"
  125. if [ -d ${HOOKS_DIR}/${HOOK}.d ]; then
  126. for script in ${HOOKS_DIR}/${HOOK}.d/* ; do
  127. [ -f $script ] && . $script
  128. done
  129. fi
  130. }
  131. # =========== tunnel interface handling ====================================
  132. do_ifconfig() {
  133. if [ -n "$INTERNAL_IP4_MTU" ]; then
  134. MTU=$INTERNAL_IP4_MTU
  135. elif [ -n "$IPROUTE" ]; then
  136. MTUDEV=`$IPROUTE route get "$VPNGATEWAY" | sed -ne 's/^.*dev \([a-z0-9]*\).*$/\1/p'`
  137. MTU=`$IPROUTE link show "$MTUDEV" | sed -ne 's/^.*mtu \([[:digit:]]\+\).*$/\1/p'`
  138. if [ -n "$MTU" ]; then
  139. MTU=`expr $MTU - 88`
  140. fi
  141. fi
  142. if [ -z "$MTU" ]; then
  143. MTU=1412
  144. fi
  145. # Point to point interface require a netmask of 255.255.255.255 on some systems
  146. if [ -n "$IPROUTE" ]; then
  147. $IPROUTE link set dev "$TUNDEV" up mtu "$MTU"
  148. $IPROUTE addr add "$INTERNAL_IP4_ADDRESS/32" peer "$INTERNAL_IP4_ADDRESS" dev "$TUNDEV"
  149. else
  150. ifconfig "$TUNDEV" ${ifconfig_syntax_inet} "$INTERNAL_IP4_ADDRESS" $ifconfig_syntax_ptp "$INTERNAL_IP4_ADDRESS" netmask 255.255.255.255 mtu ${MTU} up
  151. fi
  152. if [ -n "$INTERNAL_IP4_NETMASK" ]; then
  153. set_network_route $INTERNAL_IP4_NETADDR $INTERNAL_IP4_NETMASK $INTERNAL_IP4_NETMASKLEN
  154. fi
  155. # If the netmask is provided, it contains the address _and_ netmask
  156. if [ -n "$INTERNAL_IP6_ADDRESS" ] && [ -z "$INTERNAL_IP6_NETMASK" ]; then
  157. INTERNAL_IP6_NETMASK="$INTERNAL_IP6_ADDRESS/128"
  158. fi
  159. if [ -n "$INTERNAL_IP6_NETMASK" ]; then
  160. if [ -n "$IPROUTE" ]; then
  161. $IPROUTE -6 addr add $INTERNAL_IP6_NETMASK dev $TUNDEV
  162. else
  163. # Unlike for Legacy IP, we don't specify the dest_address
  164. # here on *BSD. OpenBSD for one will refuse to accept
  165. # incoming packets to that address if we do.
  166. # OpenVPN does the same (gives dest_address for Legacy IP
  167. # but not for IPv6).
  168. # Only Solaris needs it; hence $ifconfig_syntax_ptpv6
  169. ifconfig "$TUNDEV" inet6 $INTERNAL_IP6_NETMASK $ifconfig_syntax_ptpv6 mtu $MTU up
  170. fi
  171. fi
  172. }
  173. destroy_tun_device() {
  174. case "$OS" in
  175. NetBSD|OpenBSD) # and probably others...
  176. ifconfig "$TUNDEV" destroy
  177. ;;
  178. FreeBSD)
  179. ifconfig "$TUNDEV" destroy > /dev/null 2>&1 &
  180. ;;
  181. esac
  182. }
  183. # =========== route handling ====================================
  184. if [ -n "$IPROUTE" ]; then
  185. fix_ip_get_output () {
  186. sed -e 's/ /\n/g' | \
  187. sed -ne '1p;/via/{N;p};/dev/{N;p};/src/{N;p};/mtu/{N;p}'
  188. }
  189. set_vpngateway_route() {
  190. $IPROUTE route add `$IPROUTE route get "$VPNGATEWAY" | fix_ip_get_output`
  191. $IPROUTE route flush cache
  192. }
  193. del_vpngateway_route() {
  194. $IPROUTE route $route_syntax_del "$VPNGATEWAY"
  195. $IPROUTE route flush cache
  196. }
  197. set_default_route() {
  198. $IPROUTE route | grep '^default' | fix_ip_get_output > "$DEFAULT_ROUTE_FILE"
  199. $IPROUTE route replace default dev "$TUNDEV"
  200. $IPROUTE route flush cache
  201. }
  202. set_network_route() {
  203. NETWORK="$1"
  204. NETMASK="$2"
  205. NETMASKLEN="$3"
  206. $IPROUTE route replace "$NETWORK/$NETMASKLEN" dev "$TUNDEV"
  207. $IPROUTE route flush cache
  208. }
  209. reset_default_route() {
  210. if [ -s "$DEFAULT_ROUTE_FILE" ]; then
  211. $IPROUTE route replace `cat "$DEFAULT_ROUTE_FILE"`
  212. $IPROUTE route flush cache
  213. rm -f -- "$DEFAULT_ROUTE_FILE"
  214. fi
  215. }
  216. del_network_route() {
  217. NETWORK="$1"
  218. NETMASK="$2"
  219. NETMASKLEN="$3"
  220. $IPROUTE route $route_syntax_del "$NETWORK/$NETMASKLEN" dev "$TUNDEV"
  221. $IPROUTE route flush cache
  222. }
  223. set_ipv6_default_route() {
  224. # We don't save/restore IPv6 default route; just add a higher-priority one.
  225. $IPROUTE -6 route add default dev "$TUNDEV" metric 1
  226. $IPROUTE -6 route flush cache
  227. }
  228. set_ipv6_network_route() {
  229. NETWORK="$1"
  230. NETMASKLEN="$2"
  231. $IPROUTE -6 route replace "$NETWORK/$NETMASKLEN" dev "$TUNDEV"
  232. $IPROUTE route flush cache
  233. }
  234. reset_ipv6_default_route() {
  235. $IPROUTE -6 route del default dev "$TUNDEV"
  236. $IPROUTE route flush cache
  237. }
  238. del_ipv6_network_route() {
  239. NETWORK="$1"
  240. NETMASKLEN="$2"
  241. $IPROUTE -6 route del "$NETWORK/$NETMASKLEN" dev "$TUNDEV"
  242. $IPROUTE -6 route flush cache
  243. }
  244. else # use route command
  245. get_default_gw() {
  246. # isn't -n supposed to give --numeric output?
  247. # apperently not...
  248. # Get rid of lines containing IPv6 addresses (':')
  249. netstat -r -n | awk '/:/ { next; } /^(default|0\.0\.0\.0)/ { print $2; }'
  250. }
  251. set_vpngateway_route() {
  252. route add -host "$VPNGATEWAY" $route_syntax_gw "`get_default_gw`"
  253. }
  254. del_vpngateway_route() {
  255. route $route_syntax_del -host "$VPNGATEWAY" $route_syntax_gw "`get_default_gw`"
  256. }
  257. set_default_route() {
  258. DEFAULTGW="`get_default_gw`"
  259. echo "$DEFAULTGW" > "$DEFAULT_ROUTE_FILE"
  260. route $route_syntax_del default $route_syntax_gw "$DEFAULTGW"
  261. route add default $route_syntax_gw "$INTERNAL_IP4_ADDRESS" $route_syntax_interface
  262. }
  263. set_network_route() {
  264. NETWORK="$1"
  265. NETMASK="$2"
  266. NETMASKLEN="$3"
  267. del_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
  268. route add -net "$NETWORK" $route_syntax_netmask "$NETMASK" $route_syntax_gw "$INTERNAL_IP4_ADDRESS" $route_syntax_interface
  269. }
  270. reset_default_route() {
  271. if [ -s "$DEFAULT_ROUTE_FILE" ]; then
  272. route $route_syntax_del default $route_syntax_gw "`get_default_gw`" $route_syntax_interface
  273. route add default $route_syntax_gw `cat "$DEFAULT_ROUTE_FILE"`
  274. rm -f -- "$DEFAULT_ROUTE_FILE"
  275. fi
  276. }
  277. del_network_route() {
  278. case "$OS" in
  279. Linux|NetBSD|OpenBSD|Darwin|SunOS) # and probably others...
  280. # routes are deleted automatically on device shutdown
  281. return
  282. ;;
  283. esac
  284. NETWORK="$1"
  285. NETMASK="$2"
  286. NETMASKLEN="$3"
  287. route $route_syntax_del -net "$NETWORK" $route_syntax_netmask "$NETMASK" $route_syntax_gw "$INTERNAL_IP4_ADDRESS"
  288. }
  289. set_ipv6_default_route() {
  290. route add -inet6 default "$INTERNAL_IP6_ADDRESS" $route_syntax_interface
  291. }
  292. set_ipv6_network_route() {
  293. NETWORK="$1"
  294. NETMASK="$2"
  295. route add -inet6 -net "$NETWORK/$NETMASK" "$INTERNAL_IP6_ADDRESS" $route_syntax_interface
  296. :
  297. }
  298. reset_ipv6_default_route() {
  299. route $route_syntax_del -inet6 default "$INTERNAL_IP6_ADDRESS"
  300. :
  301. }
  302. del_ipv6_network_route() {
  303. NETWORK="$1"
  304. NETMASK="$2"
  305. route $route_syntax_del -inet6 "$NETWORK/$NETMASK" "$INTERNAL_IP6_ADDRESS"
  306. :
  307. }
  308. fi
  309. # =========== resolv.conf handling ====================================
  310. # =========== resolv.conf handling for any OS =========================
  311. modify_resolvconf_generic() {
  312. grep '^#@VPNC_GENERATED@' /etc/resolv.conf > /dev/null 2>&1 || cp -- /etc/resolv.conf "$RESOLV_CONF_BACKUP"
  313. NEW_RESOLVCONF="#@VPNC_GENERATED@ -- this file is generated by vpnc
  314. # and will be overwritten by vpnc
  315. # as long as the above mark is intact"
  316. # Remember the original value of CISCO_DEF_DOMAIN we need it later
  317. CISCO_DEF_DOMAIN_ORIG="$CISCO_DEF_DOMAIN"
  318. # Don't step on INTERNAL_IP4_DNS value, use a temporary variable
  319. INTERNAL_IP4_DNS_TEMP="$INTERNAL_IP4_DNS"
  320. exec 6< "$RESOLV_CONF_BACKUP"
  321. while read LINE <&6 ; do
  322. case "$LINE" in
  323. nameserver*)
  324. if [ -n "$INTERNAL_IP4_DNS_TEMP" ]; then
  325. read ONE_NAMESERVER INTERNAL_IP4_DNS_TEMP <<-EOF
  326. $INTERNAL_IP4_DNS_TEMP
  327. EOF
  328. LINE="nameserver $ONE_NAMESERVER"
  329. else
  330. LINE=""
  331. fi
  332. ;;
  333. search*)
  334. if [ -n "$CISCO_DEF_DOMAIN" ]; then
  335. LINE="$LINE $CISCO_DEF_DOMAIN"
  336. CISCO_DEF_DOMAIN=""
  337. fi
  338. ;;
  339. domain*)
  340. if [ -n "$CISCO_DEF_DOMAIN" ]; then
  341. LINE="domain $CISCO_DEF_DOMAIN"
  342. CISCO_DEF_DOMAIN=""
  343. fi
  344. ;;
  345. esac
  346. NEW_RESOLVCONF="$NEW_RESOLVCONF
  347. $LINE"
  348. done
  349. exec 6<&-
  350. for i in $INTERNAL_IP4_DNS_TEMP ; do
  351. NEW_RESOLVCONF="$NEW_RESOLVCONF
  352. nameserver $i"
  353. done
  354. if [ -n "$CISCO_DEF_DOMAIN" ]; then
  355. NEW_RESOLVCONF="$NEW_RESOLVCONF
  356. search $CISCO_DEF_DOMAIN"
  357. fi
  358. echo "$NEW_RESOLVCONF" > /etc/resolv.conf
  359. if [ "$OS" = "Darwin" ]; then
  360. case "`uname -r`" in
  361. # Skip for pre-10.4 systems
  362. 4.*|5.*|6.*|7.*)
  363. ;;
  364. # 10.4 and later require use of scutil for DNS to work properly
  365. *)
  366. OVERRIDE_PRIMARY=""
  367. if [ -n "$CISCO_SPLIT_INC" ]; then
  368. if [ $CISCO_SPLIT_INC -lt 1 ]; then
  369. # Must override for correct default route
  370. # Cannot use multiple DNS matching in this case
  371. OVERRIDE_PRIMARY='d.add OverridePrimary # 1'
  372. fi
  373. fi
  374. # Uncomment the following if/fi pair to use multiple
  375. # DNS matching when available. When multiple DNS matching
  376. # is present, anything reading the /etc/resolv.conf file
  377. # directly will probably not work as intended.
  378. #if [ -z "$CISCO_DEF_DOMAIN_ORIG" ]; then
  379. # Cannot use multiple DNS matching without a domain
  380. OVERRIDE_PRIMARY='d.add OverridePrimary # 1'
  381. #fi
  382. scutil >/dev/null 2>&1 <<-EOF
  383. open
  384. d.init
  385. d.add ServerAddresses * $INTERNAL_IP4_DNS
  386. set State:/Network/Service/$TUNDEV/DNS
  387. d.init
  388. # next line overrides the default gateway and breaks split routing
  389. # d.add Router $INTERNAL_IP4_ADDRESS
  390. d.add Addresses * $INTERNAL_IP4_ADDRESS
  391. d.add SubnetMasks * 255.255.255.255
  392. d.add InterfaceName $TUNDEV
  393. $OVERRIDE_PRIMARY
  394. set State:/Network/Service/$TUNDEV/IPv4
  395. close
  396. EOF
  397. if [ -n "$CISCO_DEF_DOMAIN_ORIG" ]; then
  398. scutil >/dev/null 2>&1 <<-EOF
  399. open
  400. get State:/Network/Service/$TUNDEV/DNS
  401. d.add DomainName $CISCO_DEF_DOMAIN_ORIG
  402. d.add SearchDomains * $CISCO_DEF_DOMAIN_ORIG
  403. d.add SupplementalMatchDomains * $CISCO_DEF_DOMAIN_ORIG
  404. set State:/Network/Service/$TUNDEV/DNS
  405. close
  406. EOF
  407. fi
  408. ;;
  409. esac
  410. fi
  411. }
  412. restore_resolvconf_generic() {
  413. if [ ! -f "$RESOLV_CONF_BACKUP" ]; then
  414. return
  415. fi
  416. grep '^#@VPNC_GENERATED@' /etc/resolv.conf > /dev/null 2>&1 && cat "$RESOLV_CONF_BACKUP" > /etc/resolv.conf
  417. rm -f -- "$RESOLV_CONF_BACKUP"
  418. if [ "$OS" = "Darwin" ]; then
  419. case "`uname -r`" in
  420. # Skip for pre-10.4 systems
  421. 4.*|5.*|6.*|7.*)
  422. ;;
  423. # 10.4 and later require use of scutil for DNS to work properly
  424. *)
  425. scutil >/dev/null 2>&1 <<-EOF
  426. open
  427. remove State:/Network/Service/$TUNDEV/IPv4
  428. remove State:/Network/Service/$TUNDEV/DNS
  429. close
  430. EOF
  431. ;;
  432. esac
  433. fi
  434. }
  435. # === resolv.conf handling via /sbin/netconfig (Suse 11.1) =====================
  436. # Suse provides a script that modifies resolv.conf. Use it because it will
  437. # restart/reload all other services that care about it (e.g. lwresd). [unclear if this is still true, but probably --mlk]
  438. modify_resolvconf_suse_netconfig()
  439. {
  440. /sbin/netconfig modify -s vpnc -i "$TUNDEV" <<-EOF
  441. INTERFACE='$TUNDEV'
  442. DNSSERVERS='$INTERNAL_IP4_DNS'
  443. DNSDOMAIN='$CISCO_DEF_DOMAIN'
  444. EOF
  445. }
  446. # Restore resolv.conf to old contents on Suse
  447. restore_resolvconf_suse_netconfig()
  448. {
  449. /sbin/netconfig remove -s vpnc -i "$TUNDEV"
  450. }
  451. # === resolv.conf handling via /sbin/modify_resolvconf (Suse) =====================
  452. # Suse provides a script that modifies resolv.conf. Use it because it will
  453. # restart/reload all other services that care about it (e.g. lwresd).
  454. modify_resolvconf_suse()
  455. {
  456. FULL_SCRIPTNAME=`readlink -f $0`
  457. RESOLV_OPTS=''
  458. test -n "$INTERNAL_IP4_DNS" && RESOLV_OPTS="-n \"$INTERNAL_IP4_DNS\""
  459. test -n "$CISCO_DEF_DOMAIN" && RESOLV_OPTS="$RESOLV_OPTS -d $CISCO_DEF_DOMAIN"
  460. test -n "$RESOLV_OPTS" && eval /sbin/modify_resolvconf modify -s vpnc -p $SCRIPTNAME -f $FULL_SCRIPTNAME -e $TUNDEV $RESOLV_OPTS -t \"This file was created by $SCRIPTNAME\"
  461. }
  462. # Restore resolv.conf to old contents on Suse
  463. restore_resolvconf_suse()
  464. {
  465. FULL_SCRIPTNAME=`readlink -f $0`
  466. /sbin/modify_resolvconf restore -s vpnc -p $SCRIPTNAME -f $FULL_SCRIPTNAME -e $TUNDEV
  467. }
  468. # === resolv.conf handling via UCI (OpenWRT) =========
  469. modify_resolvconf_openwrt() {
  470. add_dns $OPENWRT_INTERFACE $INTERNAL_IP4_DNS
  471. }
  472. restore_resolvconf_openwrt() {
  473. remove_dns $OPENWRT_INTERFACE
  474. }
  475. # === resolv.conf handling via /usr/bin/resolvconf (Debian, Ubuntu, Gentoo)) =========
  476. modify_resolvconf_manager() {
  477. NEW_RESOLVCONF=""
  478. for i in $INTERNAL_IP4_DNS; do
  479. NEW_RESOLVCONF="$NEW_RESOLVCONF
  480. nameserver $i"
  481. done
  482. if [ -n "$CISCO_DEF_DOMAIN" ]; then
  483. NEW_RESOLVCONF="$NEW_RESOLVCONF
  484. domain $CISCO_DEF_DOMAIN"
  485. fi
  486. echo "$NEW_RESOLVCONF" | /usr/bin/resolvconf -a $TUNDEV
  487. }
  488. restore_resolvconf_manager() {
  489. /usr/bin/resolvconf -d $TUNDEV
  490. }
  491. # ========= Toplevel state handling =======================================
  492. kernel_is_2_6_or_above() {
  493. case `uname -r` in
  494. 1.*|2.[012345]*)
  495. return 1
  496. ;;
  497. *)
  498. return 0
  499. ;;
  500. esac
  501. }
  502. do_pre_init() {
  503. if [ "$OS" = "Linux" ]; then
  504. if (exec 6<> /dev/net/tun) > /dev/null 2>&1 ; then
  505. :
  506. else # can't open /dev/net/tun
  507. test -e /proc/sys/kernel/modprobe && `cat /proc/sys/kernel/modprobe` tun 2>/dev/null
  508. # fix for broken devfs in kernel 2.6.x
  509. if [ "`readlink /dev/net/tun`" = misc/net/tun \
  510. -a ! -e /dev/net/misc/net/tun -a -e /dev/misc/net/tun ] ; then
  511. ln -sf /dev/misc/net/tun /dev/net/tun
  512. fi
  513. # make sure tun device exists
  514. if [ ! -e /dev/net/tun ]; then
  515. mkdir -p /dev/net
  516. mknod -m 0640 /dev/net/tun c 10 200
  517. [ -x /sbin/restorecon ] && /sbin/restorecon /dev/net/tun
  518. fi
  519. # workaround for a possible latency caused by udev, sleep max. 10s
  520. if kernel_is_2_6_or_above ; then
  521. for x in `seq 100` ; do
  522. (exec 6<> /dev/net/tun) > /dev/null 2>&1 && break;
  523. sleep 0.1
  524. done
  525. fi
  526. fi
  527. elif [ "$OS" = "FreeBSD" ]; then
  528. if ! kldstat -q -m if_tun > /dev/null; then
  529. kldload if_tun
  530. fi
  531. if ! ifconfig $TUNDEV > /dev/null; then
  532. ifconfig $TUNDEV create
  533. fi
  534. elif [ "$OS" = "GNU/kFreeBSD" ]; then
  535. if [ ! -e /dev/tun ]; then
  536. kldload if_tun
  537. fi
  538. elif [ "$OS" = "NetBSD" ]; then
  539. :
  540. elif [ "$OS" = "OpenBSD" ]; then
  541. if ! ifconfig $TUNDEV > /dev/null; then
  542. ifconfig $TUNDEV create
  543. fi
  544. :
  545. elif [ "$OS" = "SunOS" ]; then
  546. :
  547. elif [ "$OS" = "Darwin" ]; then
  548. :
  549. fi
  550. }
  551. do_connect() {
  552. if [ -n "$CISCO_BANNER" ]; then
  553. echo "Connect Banner:"
  554. echo "$CISCO_BANNER" | while read LINE ; do echo "|" "$LINE" ; done
  555. echo
  556. fi
  557. set_vpngateway_route
  558. do_ifconfig
  559. if [ -n "$CISCO_SPLIT_INC" ]; then
  560. i=0
  561. while [ $i -lt $CISCO_SPLIT_INC ] ; do
  562. eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
  563. eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
  564. eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
  565. if [ $NETWORK != "0.0.0.0" ]; then
  566. set_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
  567. else
  568. set_default_route
  569. fi
  570. i=`expr $i + 1`
  571. done
  572. for i in $INTERNAL_IP4_DNS ; do
  573. echo "$i" | grep : >/dev/null || \
  574. set_network_route "$i" "255.255.255.255" "32"
  575. done
  576. elif [ -n "$INTERNAL_IP4_ADDRESS" ]; then
  577. set_default_route
  578. fi
  579. if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then
  580. i=0
  581. while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do
  582. eval NETWORK="\${CISCO_IPV6_SPLIT_INC_${i}_ADDR}"
  583. eval NETMASKLEN="\${CISCO_IPV6_SPLIT_INC_${i}_MASKLEN}"
  584. if [ $NETMASKLEN -lt 128 ]; then
  585. set_ipv6_network_route "$NETWORK" "$NETMASKLEN"
  586. else
  587. set_ipv6_default_route
  588. fi
  589. i=`expr $i + 1`
  590. done
  591. for i in $INTERNAL_IP4_DNS ; do
  592. if echo "$i" | grep : >/dev/null; then
  593. set_ipv6_network_route "$i" "128"
  594. fi
  595. done
  596. elif [ -n "$INTERNAL_IP6_NETMASK" -o -n "$INTERNAL_IP6_ADDRESS" ]; then
  597. set_ipv6_default_route
  598. fi
  599. if [ -n "$INTERNAL_IP4_DNS" ]; then
  600. $MODIFYRESOLVCONF
  601. fi
  602. }
  603. do_disconnect() {
  604. if [ -n "$CISCO_SPLIT_INC" ]; then
  605. i=0
  606. while [ $i -lt $CISCO_SPLIT_INC ] ; do
  607. eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
  608. eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
  609. eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
  610. if [ $NETWORK != "0.0.0.0" ]; then
  611. # FIXME: This doesn't restore previously overwritten
  612. # routes.
  613. del_network_route "$NETWORK" "$NETMASK" "$NETMASKLEN"
  614. else
  615. reset_default_route
  616. fi
  617. i=`expr $i + 1`
  618. done
  619. for i in $INTERNAL_IP4_DNS ; do
  620. del_network_route "$i" "255.255.255.255" "32"
  621. done
  622. else
  623. reset_default_route
  624. fi
  625. if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then
  626. i=0
  627. while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do
  628. eval NETWORK="\${CISCO_IPV6_SPLIT_INC_${i}_ADDR}"
  629. eval NETMASKLEN="\${CISCO_IPV6_SPLIT_INC_${i}_MASKLEN}"
  630. if [ $NETMASKLEN -eq 0 ]; then
  631. reset_ipv6_default_route
  632. else
  633. del_ipv6_network_route "$NETWORK" "$NETMASKLEN"
  634. fi
  635. i=`expr $i + 1`
  636. done
  637. for i in $INTERNAL_IP6_DNS ; do
  638. del_ipv6_network_route "$i" "128"
  639. done
  640. elif [ -n "$INTERNAL_IP6_NETMASK" -o -n "$INTERNAL_IP6_ADDRESS" ]; then
  641. reset_ipv6_default_route
  642. fi
  643. del_vpngateway_route
  644. if [ -n "$INTERNAL_IP4_DNS" ]; then
  645. $RESTORERESOLVCONF
  646. fi
  647. if [ -n "$IPROUTE" ]; then
  648. if [ -n "$INTERNAL_IP4_ADDRESS" ]; then
  649. $IPROUTE addr del "$INTERNAL_IP4_ADDRESS/255.255.255.255" peer "$INTERNAL_IP4_ADDRESS" dev "$TUNDEV"
  650. fi
  651. # If the netmask is provided, it contains the address _and_ netmask
  652. if [ -n "$INTERNAL_IP6_ADDRESS" ] && [ -z "$INTERNAL_IP6_NETMASK" ]; then
  653. INTERNAL_IP6_NETMASK="$INTERNAL_IP6_ADDRESS/128"
  654. fi
  655. if [ -n "$INTERNAL_IP6_NETMASK" ]; then
  656. $IPROUTE -6 addr del $INTERNAL_IP6_NETMASK dev $TUNDEV
  657. fi
  658. else
  659. if [ -n "$INTERNAL_IP4_ADDRESS" ]; then
  660. ifconfig "$TUNDEV" 0.0.0.0
  661. fi
  662. if [ -n "$INTERNAL_IP6_ADDRESS" ] && [ -z "$INTERNAL_IP6_NETMASK" ]; then
  663. INTERNAL_IP6_NETMASK="$INTERNAL_IP6_ADDRESS/128"
  664. fi
  665. if [ -n "$INTERNAL_IP6_NETMASK" ]; then
  666. ifconfig "$TUNDEV" inet6 del $INTERNAL_IP6_NETMASK
  667. fi
  668. fi
  669. destroy_tun_device
  670. }
  671. #### Main
  672. if [ -z "$reason" ]; then
  673. echo "this script must be called from vpnc" 1>&2
  674. exit 1
  675. fi
  676. case "$reason" in
  677. pre-init)
  678. run_hooks pre-init
  679. do_pre_init
  680. ;;
  681. connect)
  682. run_hooks connect
  683. do_connect
  684. run_hooks post-connect
  685. ;;
  686. disconnect)
  687. run_hooks disconnect
  688. do_disconnect
  689. run_hooks post-disconnect
  690. ;;
  691. reconnect)
  692. run_hooks reconnect
  693. ;;
  694. *)
  695. echo "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
  696. exit 1
  697. ;;
  698. esac
  699. exit 0