Monday, November 3, 2008

Opensolaris, Huawei E220, Swisscom and Sunrise

I was able to open a 3G connection to Swisscom and Sunrise using a Huawei E220 3G Modem under Opensolaris.

Here are the config files (If PIN is enabled on the SIM, add OK "AT+CPIN=????" to the chat script)

Swisscom:

/etc/ppp/chat-swisscom:

ABORT BUSY
ABORT 'NO CARRIER'
ABORT ERROR
REPORT CONNECT
TIMEOUT 120
"" "AT&F"
OK "ATZ"
OK "ATQ0 V1 E1 S0=0 &C1 &D2"
#OK "AT+CPIN=????"
OK 'AT+CGDCONT=1,"IP","gprs.swisscom.ch"'
SAY "Calling Swisscom"
OK "ATDT*99***1#"
TIMEOUT 120
CONNECT ''


/etc/ppp/peers/swisscom:

term/1
115200
connect "/usr/bin/chat -V -t15 -f /etc/ppp/chat-swisscom"
idle 7200
lock
crtscts
noipdefault
modem
user "gprs"
password "gprs"
noauth
passive
usepeerdns
defaultroute
connect-delay 6000
novj
nodetach


Sunrise:

/etc/ppp/chat-sunrise:

ABORT BUSY
ABORT 'NO CARRIER'
ABORT ERROR
REPORT CONNECT
TIMEOUT 120
"" "AT&F"
OK "ATZ"
OK 'ATS7=60'
#OK "AT+CPIN=????"
OK "AT+COPS?"
OK "AT&V"
OK "AT+CSQ"
OK 'AT+CFUN=?'
OK 'AT+CGDCONT=?'
OK 'AT+CPBR=?'
OK 'AT+CPBS=?'
OK 'AT+CGDCONT=1,"IP","Internet"'
SAY "Calling Sunrise"
OK 'ATDT*99***1#'
TIMEOUT 120
CONNECT ''


/etc/ppp/peers:

term/1
115200
connect "/usr/bin/chat -V -t15 -f /etc/ppp/chat-sunrise"
idle 7200
lock
crtscts
noipdefault
modem
user ""
password ""
noauth
passive
usepeerdns
defaultroute
connect-delay 6000
novj
nodetach


Don't forget to adjust the term/? line to reflect your /dev/term/? device.

After this, just fire up "pppd call swisscom" or "pppd call sunrise" and adjust your resolv.conf. The DNS Servers are in the output. For debugging just add -d to the pppd command.

There are a few problems with the Huawei E220, as it is recognized as a storage device first, and not as a serial device.

See the Opensolaris Forum

Most of the time the modem is recognized correctly when the Modem is plugged in before booting, and doing a reconfiguration boot with grub. ( press "e" -> append "-rv" -> -> press "b" )

There is also a patch for the Eee PC's Serial USB Port driver. See Masafumi's Blog.

Good luck!

Sunday, November 2, 2008

Connecting Opensolaris to a Cisco VPN

I finally got my Opensolaris box hooked up to a Cisco VPN:


1. Get the tun/tap driver from Kazuyoshi. This driver is used for creating a using between the client and the Cisco VPN router.

2. Compile and install the driver:


pkg install sunstudioexpress
export CC=/opt/SunStudioExpress/bin/cc
./configure
make
make install



3. Download the vpnc client. This program handels the vpn connection. I've used the version 0.5.1.

4. Get gmake

pkg install SUNWgmake


5. Adjust installation paths (my personal preferences):

Makefile:

PREFIX=/opt/vpnc
ETCDIR=/opt/vpnc/etc

config.c (hardcoded locations):

Line 250: return "/opt/vpnc/etc/ssl/certs";
Line 270: return "/opt/vpnc/etc/vpnc-script";
Line 275: return "/var/run/vpnc.pid";
Line 541: ... : /opt/vpnc/etc/", ...
Line 760: ... "/opt/vpnc/etc/default.conf" ...
Line 761: ... "/opt/vpnc/etc/vpnc.conf" ...

gmake
gmake install


6. Convert the pcf file into vpnc format using /opt/vpnc/pcf2vpnc. Store the file in /opt/vpnc/etc

7. Now comes the tricky part. Create the /opt/vpnc/etc/vpnc-script -script. The script opens the connection and sets up the appropriate routing.

My target was to just have a couple of connections go through the tunnel instead of all.

Attention! If you want to have a default route set into the tunnel, be sure to add some direct routes to your vpn gateway before the default route points to the tunnel. Otherwise the vpn gateway will become unreachable and the tunnel goes down. Your remote gateway can be found in your conf file ("IPSec gateway" line).

Depending on what you want to achieve, you have to configure your DNS servers in /etc/resolv.conf manually.

Here is my sample /opt/vpnc/etc/vpnc-script :

#!/bin/sh
#* reason -- why this script was called, one of: pre-init connect disconnect
#* VPNGATEWAY -- vpn gateway address (always present)
#* TUNDEV -- tunnel device (always present)
#* INTERNAL_IP4_ADDRESS -- address (always present)
#* INTERNAL_IP4_NETMASK -- netmask (often unset)
#* INTERNAL_IP4_DNS -- list of dns serverss
#* INTERNAL_IP4_NBNS -- list of wins servers
#* CISCO_DEF_DOMAIN -- default domain name
#* CISCO_BANNER -- banner from server
#* CISCO_SPLIT_INC -- number of networks in split-network-list
#* CISCO_SPLIT_INC_%d_ADDR -- network address
#* CISCO_SPLIT_INC_%d_MASK -- subnet mask (for example: 255.255.255.0)
#* CISCO_SPLIT_INC_%d_MASKLEN -- subnet masklen (for example: 24)
#* CISCO_SPLIT_INC_%d_PROTOCOL -- protocol (often just 0)
#* CISCO_SPLIT_INC_%d_SPORT -- source port (often just 0)
#* CISCO_SPLIT_INC_%d_DPORT -- destination port (often just 0)

# =========== script (variable) setup ====================================

PATH=/sbin:/usr/sbin:$PATH

FULL_SCRIPTNAME=/usr/local/sbin/vpnc
SCRIPTNAME=`basename $FULL_SCRIPTNAME`

# =========== tunnel interface handling ====================================

do_ifconfig() {

ifconfig "$TUNDEV" inet "$INTERNAL_IP4_ADDRESS" "$INTERNAL_IP4_ADDRESS" netmask 255.255.255.255 mtu 1412 up
}

# =========== route handling ====================================

get_default_gw() {
# isn't -n supposed to give --numeric output?
# apperently not...
# Get rid of lines containing IPv6 addresses (':')
netstat -r -n | sed 's/default/0.0.0.0/' | sed 's/^.*:.*$//' | grep '^0.0.0.0' | awk '{print $2}'
}

do_pre_init() {
echo "do_pre_init"
}

do_connect() {
if [ -n "$CISCO_BANNER" ]; then
echo "Connect Banner:"
echo "$CISCO_BANNER" | while read LINE ; do echo "|" "$LINE" ; done
echo
fi

do_ifconfig
if [ -n "$CISCO_SPLIT_INC" ]; then
i=0
while [ $i -lt $CISCO_SPLIT_INC ] ; do
eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
i=`expr $i + 1`
done

fi

# Hosts 1&2 & 3
add_host_route "xx.xx.xx.xx"
add_host_route "xx.xx.xx.xy"
add_host_route "xx.xx.xx.xz"

for i in $INTERNAL_IP4_DNS ; do
add_host_route "$i"
done
}

do_disconnect() {
if [ -n "$CISCO_SPLIT_INC" ]; then
i=0
while [ $i -lt $CISCO_SPLIT_INC ] ; do
eval NETWORK="\${CISCO_SPLIT_INC_${i}_ADDR}"
eval NETMASK="\${CISCO_SPLIT_INC_${i}_MASK}"
eval NETMASKLEN="\${CISCO_SPLIT_INC_${i}_MASKLEN}"
i=`expr $i + 1`
done
fi

# Delete all routes again
del_host_route "xx.xx.xx.xx"
del_host_route "xx.xx.xx.xy"
del_host_route "xx.xx.xx.xy"


for i in $INTERNAL_IP4_DNS ; do
del_host_route "$i"
done
}

add_host_route() {
HOST="$1"
route add "$HOST" "$INTERNAL_IP4_ADDRESS" -interface
}

del_host_route() {
HOST="$1"
route delete "$HOST" "$INTERNAL_IP4_ADDRESS" -interface
}


#### Main

if [ -z "$reason" ]; then
echo "this script must be called from vpnc" 1>&2
exit 1
fi

case "$reason" in
pre-init)
do_pre_init
;;
connect)
do_connect
;;
disconnect)
do_disconnect
;;
*)
echo "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
exit 1
;;
esac

exit 0



8. Now you should be able to connect to your vpn:

/opt/vpnc/sbin/vpnc myvpn.conf


9.The output should look like this:


/usr/local/sbin/vpnc cia.conf
Enter password for tzhbomi5@bwpir.bluewin.ch:
do_pre_init
add host xx.xx.xx.xx: gateway zz.zz.zz.zz
add host xx.xx.xx.xy: gateway zz.zz.zz.zz
add host xx.xx.xx.xz: gateway zz.zz.zz.zz
VPNC started in background (pid: 3971)...


10. The interfaces look like this, where zz.zz.zz.zz is the IP Address that got assigned from the other side of the tunnel. The tun0 device was automatically created by vpnc·


ifconfig -a
lo0: flags=2001000849 mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
rge0: flags=201004843 mtu 1500 index 2
inet 192.168.1.35 netmask ffffff00 broadcast 192.168.1.255
ether 0:22:15:5e:61:2b
tun0: flags=10010008d1 mtu 1412 index 4
inet zz.zz.zz.zz --> zz.zz.zz.zz netmask ffffffff
ether 2:0:0:0:0:0