branch Attitude Adjustment packages
[12.09/packages.git] / net / openconnect / files / vpnc-script
1 #!/bin/sh
2 # List of parameters passed through environment
3 #* reason                       -- why this script was called, one of: pre-init connect disconnect
4 #* VPNGATEWAY                   -- vpn gateway address (always present)
5 #* TUNDEV                       -- tunnel device (always present)
6 #* INTERNAL_IP4_ADDRESS         -- address (always present)
7 #* INTERNAL_IP4_MTU             -- mtu (often unset)
8 #* INTERNAL_IP4_NETMASK         -- netmask (often unset)
9 #* INTERNAL_IP4_NETMASKLEN      -- netmask length (often unset)
10 #* INTERNAL_IP4_NETADDR         -- address of network (only present if netmask is set)
11 #* INTERNAL_IP4_DNS             -- list of dns servers
12 #* INTERNAL_IP4_NBNS            -- list of wins servers
13 #* INTERNAL_IP6_ADDRESS         -- IPv6 address
14 #* INTERNAL_IP6_NETMASK         -- IPv6 netmask
15 #* INTERNAL_IP6_DNS             -- IPv6 list of dns servers
16 #* CISCO_DEF_DOMAIN             -- default domain name
17 #* CISCO_BANNER                 -- banner from server
18 #* CISCO_SPLIT_INC              -- number of networks in split-network-list
19 #* CISCO_SPLIT_INC_%d_ADDR      -- network address
20 #* CISCO_SPLIT_INC_%d_MASK      -- subnet mask (for example: 255.255.255.0)
21 #* CISCO_SPLIT_INC_%d_MASKLEN   -- subnet masklen (for example: 24)
22 #* CISCO_SPLIT_INC_%d_PROTOCOL  -- protocol (often just 0)
23 #* CISCO_SPLIT_INC_%d_SPORT     -- source port (often just 0)
24 #* CISCO_SPLIT_INC_%d_DPORT     -- destination port (often just 0)
25 #* CISCO_IPV6_SPLIT_INC         -- number of networks in IPv6 split-network-list
26 #* CISCO_IPV6_SPLIT_INC_%d_ADDR -- IPv6 network address
27 #* CISCO_IPV6_SPLIT_INC_$%d_MASKLEN -- IPv6 subnet masklen
28
29 # FIXMEs:
30
31 # Section A: route handling
32
33 # 1) The 3 values CISCO_SPLIT_INC_%d_PROTOCOL/SPORT/DPORT are currently being ignored
34 #   In order to use them, we'll probably need os specific solutions
35 #   * Linux: iptables -t mangle -I PREROUTING <conditions> -j ROUTE --oif $TUNDEV
36 #       This would be an *alternative* to changing the routes (and thus 2) and 3)
37 #       shouldn't be relevant at all)
38 # 2) There are two different functions to set routes: generic routes and the
39 #   default route. Why isn't the defaultroute handled via the generic route case?
40 # 3) In the split tunnel case, all routes but the default route might get replaced
41 #   without getting restored later. We should explicitely check and save them just
42 #   like the defaultroute
43 # 4) Replies to a dhcp-server should never be sent into the tunnel
44
45 # Section B: Split DNS handling
46
47 # 1) Maybe dnsmasq can do something like that
48 # 2) Parse dns packets going out via tunnel and redirect them to original dns-server
49
50 do_connect() {
51         if [ -n "$CISCO_BANNER" ]; then
52                 echo "Connect Banner:"
53                 echo "$CISCO_BANNER" | while read LINE ; do echo "|" "$LINE" ; done
54                 echo
55         fi
56
57         proto_init_update "$TUNDEV" 1
58
59         if [ -n "$INTERNAL_IP4_MTU" ]; then
60                 MTU=$INTERNAL_IP4_MTU
61         fi
62
63         if [ -z "$MTU" ]; then
64                 MTU=1412
65         fi
66
67         proto_add_ipv4_address "$INTERNAL_IP4_ADDRESS" 32 "" "$INTERNAL_IP4_ADDRESS"
68
69         if [ -n "$INTERNAL_IP4_NETMASKLEN" ]; then
70                 proto_add_ipv4_route "$INTERNAL_IP4_NETADDR" "$INTERNAL_IP4_NETMASKLEN"
71         fi
72
73         # If the netmask is provided, it contains the address _and_ netmask
74         if [ -n "$INTERNAL_IP6_ADDRESS" ] && [ -z "$INTERNAL_IP6_NETMASK" ]; then
75             INTERNAL_IP6_NETMASK="$INTERNAL_IP6_ADDRESS/128"
76         fi
77
78         if [ -n "$INTERNAL_IP6_NETMASK" ]; then
79                 addr="${INTERNAL_IP6_NETMASK%%/*}"
80                 mask="${INTERNAL_IP6_NETMASK##*/}"
81                 [[ "$addr" != "$mask" ]] && proto_add_ipv6_address "$addr" "$mask"
82         fi
83
84         [ -n "$INTERNAL_IP4_DNS" ] && proto_add_dns_server "$INTERNAL_IP4_DNS"
85         [ -n "$CISCO_DEF_DOMAIN" ] && proto_add_dns_search "$CISCO_DEF_DOMAIN"
86
87         if [ -n "$CISCO_SPLIT_INC" ]; then
88                 i=0
89                 while [ $i -lt $CISCO_SPLIT_INC ] ; do
90                         eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
91                         eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
92                         eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
93                         if [ $NETWORK != "0.0.0.0" ]; then
94                                 proto_add_ipv4_route "$NETWORK" "$NETMASKLEN"
95                         else
96                                 proto_add_ipv4_route "0.0.0.0" 0
97                         fi
98                         i=$(($i + 1))
99                 done
100         elif [ -n "$INTERNAL_IP4_ADDRESS" ]; then
101                 proto_add_ipv4_route "0.0.0.0" 0
102         fi
103         if [ -n "$CISCO_IPV6_SPLIT_INC" ]; then
104                 i=0
105                 while [ $i -lt $CISCO_IPV6_SPLIT_INC ] ; do
106                         eval NETWORK="\${CISCO_IPV6_SPLIT_INC_${i}_ADDR}"
107                         eval NETMASKLEN="\${CISCO_IPV6_SPLIT_INC_${i}_MASKLEN}"
108                         if [ $NETMASKLEN -lt 128 ]; then
109                                 proto_add_ipv6_route "$NETWORK" "$NETMASKLEN"
110                         else
111                                 proto_add_ipv6_route "::0" 0
112                         fi
113                         i=$(($i + 1))
114                 done
115         elif [ -n "$INTERNAL_IP6_NETMASK" -o -n "$INTERNAL_IP6_ADDRESS" ]; then
116                 proto_add_ipv6_route "::0" 0
117         fi
118         proto_send_update "$INTERFACE"
119 }
120
121 do_disconnect() {
122         proto_init_update "$TUNDEV" 0
123         proto_send_update "$INTERFACE"
124 }
125
126 #### Main
127
128 if [ -z "$reason" ]; then
129         echo "this script must be called from vpnc" 1>&2
130         exit 1
131 fi
132 if [ -z "$INTERFACE" ]; then
133         echo "this script must be called for an active interface"
134         exit 1
135 fi
136
137 . /lib/netifd/netifd-proto.sh
138
139 case "$reason" in
140         pre-init)
141                 ;;
142         connect)
143                 do_connect
144                 ;;
145         disconnect)
146                 do_disconnect
147                 ;;
148         reconnect)
149                 ;;
150         *)
151                 echo "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
152                 exit 1
153                 ;;
154 esac
155
156 exit 0