Tuesday, 15 December 2009

How to: make use of a locked VoIP ATA with asterisk

So you've got a VoIP ATA but it's locked to one provider and you want to make better use of it?
You've searched all over the net on how to crack or hack the firmware to unlock it but given up all hope?

Well, I've worked out an interesting way to get around this problem. This works with my Netgear TA612V that is locked to MyNetFone here in Australia. Essentially, what you can do is set up an asterisk server to pretend to be your provider. Here is roughly how I did it:

You'll need:
- a DNS server such as bind (and know how to set it up)
- to be able to redirect DNS requests to your bind server (some ATA's don't use your network's DNS server provided by DHCP) - i.e. you'll need to be able to add a port redirect on your router
- asterisk and the desire to learn how it works and to set it up

A note, my server has the IP address

1) Set up bind to redirect the domain name of your provider's sip server to your own. I did this by setting up a hosts file in bind for sip01.mynetfone.com.au and adding the following host:

sip01.mynetfone.com.au. IN A

2) Redirect all UDP port 53 requests from your local network (but not your server!) to your server. I use shorewall firewall and did that with the following line:

REDIRECT loc 53 udp 53 - ! # Transparent DNS

3) Add accounts in your asterisk sip.conf for your ATA to log into. The following is what worked with my TA612V:

[09*****4] ; ATA line 1

[09*****5] ; ATA line 2

Naturally, I've *'d out my username and password. A note, I originally found that this didn't work if I had both lines set up in Asterisk (there was a bug with the TA612V and old versions of asterisk) however, with 1.6.2 this seems to be fine now.

You'll then need to edit extensions.conf in asterisk to create dialling plans. Unfortunately, as the ATA will be programmed with you'r providers dialing plans, you won't be able to set up extensions (dial 1 to 9 for each extension or dial 0 for an outside line). What I mean by this is that (for example) my ATA is set up to accept either a 10 digit number if the first digit is 0 (eg 02xxxxxxxx or 04xxxxxxxx) a 10 digit number for numbers starting with 1300 or 1800, a 6 digit number for other 13xxxx numbers and also to send 121 to voicemail. This is all needed because the ATA needs to know how many number presses to wait for before it sends the dialled number and create the call.

This is how I set up my extensions.conf

exten => _X.,1,Dial(SIP/${EXTEN}@othersipprovider)
exten => _121,1,Dial(SIP/111@othersipprovider)
exten => _09X.,1,Dial(SIP/${EXTEN}@mynetfone)

You can see I've set up outgoing calls to go via an alternative sip provider, I've configured dialling 121 to go to my other sip provider's voicemail (which is 111) and I've configured all 09 numbers to go via mynetfone (as 09XXXXXX is the format of mynetfone's direct numbers). In theory, you could set up an extension (like 121) to connect you to an asterisk IVR extension where you could select which extension to dial or which provider to dial out on. I'm thinking of doing this but haven't had the time to look into this. Asterisk is an immensely powerful voice service and the possibilities are endless once you've got your ATA working with it.

Legalities: Whilst hacking or cracking the firmware of a locked ATA is definitely a grey area legally, (whilst I'm no lawyer) I feel that the above approach is generally OK. In doing the above at no stage have you had to reverse engineer any form of encryption or even modify the firmware of your ATA.

What surprised me is that there is no challenge/handshake authentication that occurs between these ATA's and the provider. In theory it would be incredibly easy to intercept these authentication details on a network and hack into someone's SIP account (just use some packet sniffing software and you can see for yourself the SIP authentication process with your username and password there in plain text) - however this would be illegal, I'm just pointing out how insecure I found the whole system to be!

Finally, I know I haven't been very detailed with this how-to but the reasons are:
1) I'm short on time at the moment
2) There are a huge number of combinations of the tools and devices and providers - I've provided you with the idea on how to do it, it's up to you to work out how to do this with your setup

Saturday, 27 June 2009

SATA AHCI mode on systems without BIOS option

I've got a Dell Poweredge SC430 I bought a couple of years back.
I recently put 4 new WD 1TB drives in it which support native command queuing and installed the latest Ubuntu 9.04 whilst I was rebuilding my server.
Anyway, I noticed linux was only using the ata_piix module for my onboard SATA ICH7 family controller (integrated in the Intel Chipset). As some background, many SATA controllers offer a legacy mode (ATA/IDE emulation mode) and native mode (AHCI or RAID). Normally you can change which mode the controller is in via the BIOS hoever for whatever reason Dell chose not to include this option in my system.

Problem: The hardware ID that the controller reports to the system is dependant on which mode the controller is in. This means that the OS can load the appropriate driver depending on the mode of the controller. For Windows users the solution is aparently easy, you can force Windows to use the AHCI driver when the controller is still in the legacy mode. I presume the driver then detects that the controller is in legacy mode and instructs it to change to AHCI mode on the fly.

Unfortunately for linux this isn't exactly easy to do. To force linux to use a particular module with hardware that it doesn't have it must have it's hardware ID listed in the driver when the module is built. This means compiling the kernel from source. This also means re-compiling the kernel from source whenever you want to update your kernel, not something I want to have to deal with.

Fortunately some clever Mac Pro users have found another way. Instead of modifying the linux kernel, they edited the stage1 part of the grub bootloader to add some assembly commands to instruct the controller to switch modes. This is a fantastic hack for several reasons:
  1. As grub can boot virtually any OS, this hack will ensure AHCI mode is available for any OS, not just linux
  2. Grub, and especially the stage1 file, is relatively static and doesn't get updated too often, so no need to worry about patching new versions continually
  3. No need to worry about kernel updates clobbering the patch and no need to compile the kernel from source every time there is an update
Solution: Note, at the time of writing this, I used grub 0.97, you might need to change some directory paths appropriately if you use a different version.

This patch, whilst originally written for a Mac Pro with an Intel 631xESB/632xESB Controller just happens to work perfectly on my Dell with an ICH7 Controller. Note that I did indeed verify that the commands to switch SATA mode were identical by comparing the Intel documentation here: http://www.intel.com/Assets/PDF/datasheet/313082.pdf Port Mapping Register (SATA–D31:F2) on page 764 and here: http://www.intel.com/Assets/PDF/datasheet/307013.pdf Sub Class Code Register (SATA–D31:F2) on page 495.

You should verify at least two things before trying this patch:
  • ensure your chipset supports AHCI (not all ICH7 variants do)
  • ensure your chipset has the same format command at the same offset to switch modes (if it is an Intel, I'd hope that they're consistent, they seem to be so far)
If you're happy to try this out, here's how you do it:
  1. Get the source of grub, in ubuntu:
    sudo apt-get source grub
  2. If you're using and x64 OS you'll need the 32bit libc dev files:
    sudo apt-get install libc6-dev-i386
  3. Get the patch:
  4. Apply the patch
    patch grub-0.97/stage1/stage1.S grub-0.97_macpro_esb2_ahci_stage1_new.patch
  5. Configure grub
    cd grub-0.97; ./configure
  6. Build grub:
    make all
  7. Find your grub installed libraries. eg:
    cd /usr/lib/grub/x86_64-pc
  8. Backup your grub existing grub stage1 file
  9. Copy the compiled stage1 to your grub library directory
  10. Update your grub bootloader. eg:
    grub-install hd0
  11. Note: grub-install will overwrite /boot/grub/stage1 with the stage1 from your library directory so you'll need to make sure you're putting the patched stage1 in the library directory NOT the /boot/grub or equivalent directory
  12. Reboot and verify your controller is now using the ahci module!