Android: AT&T Captivate’s wifi networking is broken

by nc on August 27, 2010 · 12 comments

AT&T Captivate (Samsung Galaxy S)

I’ve finally made the switch from Windows Mobile to Android by way of an AT&T Captivate (which is one of the many Samsung Galaxy S phones.) So far, I’ve been fairly happy – app selection is good, it’s great to have the ability to tinker on it (no, have not rooted it or flashed a custom rom yet), and the screen is great. The only major downfalls I’ve run into so far are the lack of a hardware keyboard (I am so used to being able to type on my phone without looking — I know that there are Android options that have a full keyboard, but I wanted the combination of a full keyboard with a large high-res screen and a fast processor.. the only options available right now are on carriers that I don’t want to go with. However, the T-Mobile G2 looks like it would have fit the bill — too bad I already bought!) and the weak integrated mail client — fortunately K-9 Mail took care of that one.

I’ve only run into one thing which really causes problems that I haven’t been able to fix yet — Samsung’s Android build seems to use old-fashioned classful addressing instead of honoring modern CIDR, and then hides the fact that it is doing that from the user. This means that if you are on a Wifi network that assigns an IP in 10.0.0.0/8, it will assign your netmask as 255.0.0.0 at the OS level, and you will not be able to reach any other subnets in 10.0.0.0/8. This won’t be a problem for the majority of users out there, but for people who have advanced home networks (me!), or connect to a corporate/campus network with their phone, it is likely to completely break the ability to use the network.

Oddly, if you look at the networking on the phone using a tool such as Network Info II, it will always show your netmask as the netmask that the DHCP server sent you. This is what really confused me for awhile — Network Info showed the proper netmask, but I couldn’t reach anything on 10.0.0.0/8 outside of the /24 that my phone’s IP was in. Finally, I figured out how to get the Android SDK working, and accessed the phone using adb. Here’s what I found:

nc@nc-desktop:~$ adb shell
$ ifconfig eth0
eth0: ip 10.0.55.201 mask 255.0.0.0 flags [up broadcast running multicast]
$

*Ahem* – no, my netmask is *not* 255.0.0.0. ;) At this point I assumed that the apps that were displaying 255.255.255.0 at the UI level were just assuming that was my netmask, and figured that it was a problem with the way that my DHCP server was configured. I started to dig around the filesystem, and found the /system/etc/dhcpcd directory — the dhcpcd configuration. The file /system/etc/dhcpcd/dhcpcd-hooks/95-configured looked interesting – it appeared to dump out the ip configuration that it received from the dhcp server into the system properties:

case "${reason}" in
BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|IPV4LL)
    setprop dhcp.${interface}.ipaddress "${new_ip_address}"
    setprop dhcp.${interface}.gateway   "${new_routers%% *}"
    setprop dhcp.${interface}.mask      "${new_subnet_mask}"
    setprop dhcp.${interface}.leasetime "${new_dhcp_lease_time}"
    setprop dhcp.${interface}.server    "${new_dhcp_server_identifier}"

    setprop dhcp.${interface}.result "ok"
    ;;

I figured that I should be able to use ‘getprop’ to see what was set there; I gave it a shot..

[dhcp.eth0.result]: [ok]
[init.svc.dhcpcd]: [running]
[dhcp.eth0.pid]: [26234]
[dhcp.eth0.reason]: [BOUND]
[dhcp.eth0.dns1]: [8.8.8.8]
[dhcp.eth0.dns2]: [8.8.4.4]
[dhcp.eth0.dns3]: []
[dhcp.eth0.dns4]: []
[dhcp.eth0.ipaddress]: [10.0.55.201]
[dhcp.eth0.gateway]: [10.0.55.254]
[dhcp.eth0.mask]: [255.255.255.0]
[dhcp.eth0.leasetime]: [7200]
[dhcp.eth0.server]: [10.0.55.254]

What do you know – it was receiving the info from the DHCP server and processing it correctly! So this means that whatever utility dhcpcd is using to set up the IP interface must not be working properly, and assuming classful networking.

There are a few posts around the ‘net on this; first, a forum post at AT&T, and then something I posted at xda-developers; however, nobody’s had any luck figuring out why this is yet, or how to fix it (short of rooting the phone.) One workaround is to configure a static IP, but that’s a lame solution.

If anyone knows how to get this working properly I’d love to hear about it! :)

{ 12 comments… read them below or add one }

Kevin August 28, 2010 at 10:48 pm

classful addressing is so 1992

Reply

nc August 29, 2010 at 9:18 am

Dude! Tell me about it!

Reply

Toan September 1, 2010 at 3:26 am

Hey, I’ve got a solution to it though – but you needa root it first…
Ok, the weird thing is that for any DHCP network, the captivate just automatically assign a netmask of 255.255.0.0 (in my case), so what you should do is assigning a new netmask manually. Doing that by:
1- Root the device
2- Download Busybox (from Market)
3- Download OSMonitor (optional) to check your current netmask address
4- Download GScript from Market
5- Run this script in GScript: busybox ifconfig eth0 netmask 255.255.255.0
6- Done – you need to run GScript anytime you want to connect to the internet.
It seems like a problem for ALL Captivate

Reply

nc September 1, 2010 at 9:15 am

Thanks Toan! Do you happen to have the reference link on xda-developers? I’ve failed to find any discussion of this whatsoever on there. ;(

Now I might have to root the phone.. sigh. I’ve been fairly happy pre-rooted so far. ;)

Reply

joe November 16, 2010 at 8:55 am

Hi i have the int’l (regular) i9000 and tried ur fix and i kept on getting an error ‘cannot assign requested address’.. the static ip fix works but i’m just looking for a permanent fix cos the phone might not connect to other wifi networks

Reply

nc November 19, 2010 at 8:04 am

If you are on a stock i900, have you tried the Froyo builds? They are supposed to fix many of the wireless issues that I’ve heard about.

Reply

Toan September 1, 2010 at 3:28 am

PS: Credit goes to tmusall :) a member of xda-developers forum :)

Reply

Reetika September 1, 2010 at 12:20 pm

Hi,
I have an SGS (GT-I9000 – they don’t come with contracts in India), and am facing serious problems connecting to my home Wifi. I have a Netgear router, and the phone’s wifi worked great for the first week, no signal drops or anything. It suddenly refused to work this week, and hasn’t since then. Have read of this happening on other forums. When I turn Wifi on, it just shows up as connected to Netgear, but nothing works. Any workaround without rooting? Also, if I use static IP, where will I find each of those information areas to fill in? Thanks in advance!

Reply

nc September 1, 2010 at 12:25 pm

I had a similar issue on my Captivate when I was messing around with the CIDR (or lack thereof) issue; suddenly the phone couldn’t get an IP on any wifi network.. after some googlin’ it appeared to be a relatively common problem, unfortunately the fix was to do a factory reset on the phone. ;(

On the Captivate, you can get to the static IP settings while in the wifi configuration menu by hitting the menu button, then advanced.. it may be different on a stock Galaxy S; I’m not sure how much ATT customizes the ROM.

Reply

Shane R. Spencer September 7, 2010 at 1:38 pm

I’ve resolved this internally for now by specifying a static route on my DHCP server. In this case it is dhcp3-server running on top of Debian Linux.

I have 5 or so subnets at work. WiFi is on it’s own. Here is the range statement for WiFi which publishes a static route to the DHCP client on the Captivate.

subnet 10.1.2.0 netmask 255.255.255.0 {
range 10.1.2.100 10.1.2.199;
option static-routes 10.1.0.0 10.1.2.1;
}

And the result:

# ./ip route
10.1.2.0/24 dev eth0 src 10.1.2.139
10.1.0.0/16 via 10.1.2.1 dev eth0
10.0.0.0/8 dev eth0 src 10.1.2.139
default via 10.1.2.1 dev eth0

Huzzah – for now.

Reply

nc September 7, 2010 at 1:47 pm

Ah! Good idea.. I will give that a shot once I get back to the house. ;)

I assume you are root’d, and therefore able to run ‘ip route’?

Reply

Shane R. Spencer September 7, 2010 at 1:56 pm

indeed. linked busybox to several bins in the ~/

lrwsrwsrwt root root 2010-08-31 06:24 ash -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:52 cp -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:24 ls -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:25 ip -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:25 arp -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:26 hostname -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:26 uptime -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:26 uname -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:28 wget -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:56 fnd -> /system/xbin/busybox
lrwsrwsrwt root root 2010-09-05 00:14 netstat -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:56 find -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:57 grep -> /system/xbin/busybox
lrwsrwsrwt root root 2010-08-31 06:58 less -> /system/xbin/busybox
lrwsrwsrwt root root 2010-09-05 00:15 ps -> /system/xbin/busybox
lrwsrwsrwt root root 2010-09-05 00:30 whoami -> /system/xbin/busybox
lrwsrwsrwt root root 2010-09-05 18:58 free -> /system/xbin/busybox
lrwsrwsrwt root root 2010-09-05 19:45 nano -> /system/xbin/busybox
lrwsrwsrwt root root 2010-09-05 19:45 vi -> /system/xbin/busybox

Reply

Leave a Comment

Previous post:

Next post: