Hack 4. Connect Linux with a Bluetooth Phone

Use your Bluetooth phone as a modem when Wi-Fi isn't available.

No doubt the novelty of being able to scan for nearby Bluetooth devices from your Linux machine will wear off all too soon, and then you'll want to actually do things with your shiny new Bluetooth connection. Being able to use your cell phone as a modem from all those places you can't pull in a Wi-Fi signal would be pretty cool, wouldn't it?

Bluetooth supports a number of profiles, which define the way that Bluetooth devices can communicate with each other. In this case, we want to make use of the Dial-up Networking (DUN) profile, which relies on a protocol called RFCOMM to emulate a serial link between two devices. You can use RFCOMM to connect your Linux box to your phone, and then run pppd over the link to get access to the Internet. This should work using various mobile data protocols including CDPD, GPRS, EDGE, 1xRTT, and 1xEV-DO. More information on the various mobile data acronyms can be found in Appendix A.

1.5.1. Pairing Your Phone

Assuming you've got Bluetooth working [Hack #1], you should be able to bring your phone within range of your computer and scan for it using hcitool. We'll presume that you've done this, and that hcitool reports a BD address for your phone of 00:11:22:33:44:55.

You can also use sdptool to verify that there's a device in range that supports the DUN profile:

sdptool search DUN Inquiring … Searching for DUN on 00:11:22:33:44:55 … Service Name: Dial-up Networking Service RecHandle: 0x10001 Service Class ID List: "Dialup Networking" (0x1103) "Generic Networking" (0x1201) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 1

Note this channel number, because you'll need it later. As you can see, hcitool and sdptool offer a lot of other useful Bluetooth diagnostic functions, which you can read more about on their respective manpages.

Before you can actually connect to the phone, however, you may need to set up what's referred to as device pairing between your Linux box and your phone, so that your phone knows to allow your computer access to its services, and possibly vice versa. Your computer's PIN can be found in /etc/ bluetooth/pin, and you will want to alter this to a unique value that only you know.

It's important to note here that Bluetooth pairing is not a very secure process. Security researchers have found ways to hijack the pairing process and even force a re-pairing remotely. Until workarounds are found, the best thing you can do is change your PIN frequently, and use a PIN of the maximum length of 16 characters.

Most phones have a Bluetooth PIN that you can configure within the phone itself. The BlueZ stack comes with a little Python utility called bluepin that pops up a GTk+ dialog to ask for your phone's PIN as needed.

If you don't want to be bothered with pop-up windows, the following Perl script can be saved to /etc/bluetooth/pindb, and you can use it store PINs for multiple Bluetooth devices:

#!/usr/bin/perl while ( ) { print "PIN:$1 " if /^$ARGV[1]s+(w+)/o; } _ _DATA_ _ # Your Bluetooth PINs can go here, in BD address / PIN pairs, # one to a line, separated by whitespace. # 00:11:22:33:44:55 11111

Make sure that /etc/bluetooth/pindb is owned by root and is chmod 0700you don't want other users being able to look up your PINs. The options section of your /etc/bluetooth/hcid.conf should accordingly look something like this:

options { autoinit yes; security auto; pairing multi; pin_helper /etc/bluetooth/pindb; }

This ensures that HCI devices are configured at boot, that pairing is allowed, and that hcid will check pindb for your PINs on a per-device basis. Be sure to restart hcid by running /etc/init.d/bluetooth restart if you made any changes to your /etc/bluetooth/hcid.conf.

Now that your computer is set up for pairing, you'll have to set up your phone similarly, for which you'll need to refer to your user's manual. This set-up process often requires that the phone scan for your computer's Bluetooth adapter, so be sure that your computer is within range with a working Bluetooth adapter. The interface will probably come up as BlueZ (0) or something similar, unless you changed the name option in your hcid.conf. You probably want to set up the pairing on the phone as TRusted, or the equivalent, so that the phone doesn't ask you to verify the connection each time you try to dial out from your Linux box.

Now that we have found a device in range that offers dial-up networking, and set up pairing with it, the next step is to bind an RFCOMM interface to that device. First, make sure that there are RFCOMM entries in your /dev directory, using ls -l /dev/rfcomm*. If ls reports "No such file or directory," you can easily create 64 RFCOMM device entries by switching to the superuser and doing the following:

# for n in `seq 0 63`; do mknod -m660 /dev/rfcomm$n c 216 $n; done # chown root:uucp /dev/rfcomm*

If you're running Debian or Ubuntu, you will want to chown your RFCOMM devices to group dialout, instead of uucp.

Now, as the superuser, bind /dev/rfcomm0 to your phone on the channel reported for DUN by sdptool earlier, using the rfcomm utility from bluezutils:

# rfcomm bind /dev/rfcomm0 00:11:22:33:44:55:66 1

You'll know that the device was bound successfully if, like any good Unix utility, rfcomm just returns silently. You can demonstrate that it did actually work, however, by running rfcomm without any arguments:

# rfcomm rfcomm0: 00:11:22:33:44:55 channel 1 clean

 

1.5.2. Configuring PPP Networking

Now you can just treat this serial device as if it were an ordinary modem. Just to prove it, try running minicom as root, and switch the serial device to /dev/rfcomm0. When the terminal loads, type AT and press Enter. If the phone responds OK, then congratulations are in orderyou're talking to your cell phone over a Bluetooth connection.

Before going any further, you might want to add the following to your /etc/bluetooth/rfcomm.conf so that the RFCOMM device is configured by default when Bluetooth loads:

rfcomm0 { # Automatically bind the device at startup bind yes; device 00:11:22:33:44:55; channel 1; comment "My Phone"; }

From here, it's just a short hop to getting your computer on the Net. Put the following into /etc/ppp/peers/gprs:

/dev/rfcomm0 connect '/usr/sbin/chat -v -f /etc/ppp/peers/gprs.chat' noauth defaultroute usepeerdns lcp-echo-interval 65535 debug

Then, save the following as /etc/ppp/peers/gprs.chat:

TIMEOUT 15 ECHO ON HANGUP ON '' AT OK ATZ OK ATD*99#

Alternately, if you prefer using wvdial, try adding the following to your /etc/wvdial.conf:

[Dialer gprs] Modem = /dev/rfcomm0 Phone = *99# Username = foo Password = bar

Note that while European providers give you a username and password, in the United States you still need to supply dummy values to satisfy wvdial. Consult your network provider's web site for details about what values you may need to use. Your GPRS is actually already authenticated by your very presence on the cellular network, so you don't have to re-authenticate just to use PPP. The phone number listed in the previous configuration files is the standard GPRS dial-up number, which may work for you right off the bat if your phone is configured properly.

Most GSM phones support multiple GPRS access points, so if the default for your phone doesn't work for you, try going into minicom and typing AT+CGDCONT? followed by a carriage return. Your phone should respond with a list of available Packet Data Protocol (PDP) contexts. Pick the one that seems the most appropriate, and then set your GPRS phone number in /etc/wvdial.conf to *99***n#, replacing n with the number of the PDP profile you want to use. Failing that, try contacting your service provider for advice.

You can test this setup as root by running either pppd call gprs or wvdial gprs, depending on your setup, and watching /var/log/messages in another window. The only hitch with this setup is that it doesn't set up your nameservers in /etc/resolv.conf by default. The way around this on Red Hat and Fedora is to store the following in /etc/sysconfig/network-scripts/ifcfg-ppp0 (or ppp1, ppp2, etc., as you prefer):

# comment out CHATSCRIPT and uncomment WVDIALSECT if you're using wvdial DEVICE=ppp0 MODEMPORT=/dev/rfcomm0 CHATSCRIPT=/etc/ppp/peers/gprs.chat # WVDIALSECT=gprs

This way you can just use ifup ppp0 and ifdown ppp0 to bring the link up and down. To get the identical result on Debian, use the pppd configuration just shown and add the following to your /etc/network/interfaces:

iface ppp0 inet ppp provider gprs

If you're not using a Red Hat-or Debian-like distribution, you can always just add the following additional lines to your /etc/ppp/peers/gprs to make DNS work right, and use pppd call gprs and killall pppd to bring the link up and down:

welcome 'cp -b /etc/ppp/resolv.conf /etc/resolv.conf' disconnect 'mv /etc/resolv.conf~ /etc/resolv.conf'

That's just about all you need to know to get online from anywhere you can get GSM service. Just don't expect blistering speeds from it: as of this writing, GPRS ranges in speed from under 5k/s to just over 20k/s, depending on your servicenot exactly high speed by modern standards, but amazingly usable where you would otherwise have nothing at all.

1.5.3. Hacking the Hack

As a little bonus, here's a short iptables script to let you share that GPRS with anyone in Wi-Fi range, and which could be stored as or called from /etc/ppp/ip-up.local:

# Enable IP forwarding and rp_filter (to kill IP spoof attempts). echo "1" > /proc/sys/net/ipv4/ip_forward echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter # Load relevant kernel modules, if necessary. for i in ip_tables ipt_MASQUERADE iptable_nat ip_conntrack ip_conntrack_ftp ip_conntrack_irc ip_nat_irc ip_nat_ftp; do modprobe $i 2>/dev/null; done # Masquerade anything that's not from a PPP interface # (e.g. ethernet, Wi-Fi, etc.) iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE

But what, you ask, about regular dial-up connections? How about faxes? Well, it turns out that you're in luck: simply replace the GPRS access number with any regular phone number of your choice and (on most phones) you get a 9,600 baud data connection to that line. Configuring efax or mgetty-sendfax to use Bluetooth to fax from a GSM phone in this manner is therefore left as an exercise for the reader.

Schuyler Erle

Категории