开源无线路由器固件上 Bug 的故事(二)

上一篇文章花了很大的气力讲了开放源代码第三方家用无线路由器固件的基本情况和绕过这个 bug 的办法。绕过 bug 在很多时候不失为一种有效的选择,特别是像之前我遇到的情况:开发组在一年内都没有对 bug report 作出任何响应。所以在失望之余也只好另辟奚径了,再用俗话说一遍就是“惹不起,躲得起”。 😉

下面把话说回来,毕竟文章的主题是 Bug 的故事,所以还是要接着往下说。只是后面的东西更偏向于技术,所以比较枯燥一点。

3. Bug 的认定和定位

这个 Bug 之所以让我记恨于心,的确是因为它太复杂了:从 bug 的发现认定,到 bug 定位和 bugfix,由于没有正式的官方支持,OpenSource Community 这种散兵游勇的开发全靠分散在各地的个人,每一步的进展都很艰难。

这个 Bug 造成的问题是目的MAC地址为 00-80-C2-00-00-03 的 802.1X 多播认证包被无线路由器丢弃(不会转发到 WAN 口),这样在路由器上运行的 Supplicant 程序在发出 logon request 之后便再也收不到回复。问题其实很明显,因为使用同一个程序,把网线插到 PC  上便能通过认证,显然就是路由器处理的问题。

那为什么说 bug 认定是一件麻烦事呢?因为后来才确定这个 bug 只存在于 Broadcom® 公司的 Roboswitch™ 系列交换芯片中。早期的 Linksys WRT54G 路由器使用的是 ADM6996L 交换芯片(ADMTek 已经被 Infineon 收购),在进行认证的时候是没有问题的。所以这个问题在此型号的机器上无法重现,再加上大家都从软件角度来思考(其实这是个硬件问题)。最后导致了两种声音:一种声音坚定地说自己遇到了 OpenWRT 的 bug,另一种声音说,这个 bug 在我的机器上无法重现,不能认定。这两种声音可以在 OpenWRT Trac 上的 Ticket 1862 看到。

 接下来有人发现“It has also worked for me on WRT54G 1.0-2.0. On WRT54G 4.0 it does not work.”,大家这才意识到这是 BCM5325 交换芯片搞的鬼。后来的 BCM5352 和 BCM5354 芯片内部都集成了一个交换模块,因此也理所当然地继承了这个 bug 。

修订:根据 jacky235 的消息,8230-4 和 WZR-G108 使用了 BCM5325A2KQM 交换芯片,但可以通过认证。而 OpenWRT Ticket 1862 上出现问题的是 BCM5325E 交换芯片,此芯片支持额外的管理功能和 802.1x EAPOL filtering 。所以将出问题的交换芯片定位到 BCM5325E 上面。集成了交换芯片的 BCM5352 和BCM5354 依然有问题,这个我自己可以证实。

此 Bug 的产生机理是什么呢?其实话说回来,这本来是 Braodcom 设计出来的 feature ,目的是为了使交换芯片的工作模式更加灵活一些,可是 Broadcom 的保守和封锁让这个 feature 在这里适得其反。(关于bug 和feature 的辩证关系,请看 atppp 的文章)如果芯片工作在 Default Mode ,那么会丢弃 802.1x 认证多播包 00-80-c2-00-00-03 ,如果芯片工作在 Frame-Management Mode ,则会把此包转发到 Frame Management Port 。如此简单的逻辑

4. Bugfix 和当前问题

这个 bug 的修复就更棘手了。人们总算搞清楚了问题的所在,但就是没办法去修复它。因为你无论是 Google、Yahoo 还是百度都找不到详细的 BCM5325 芯片资料。所有宣称有 Datasheet 的网站上下载回来的只有两页纸的 Product Brief。这东东在 Broadcom 自己的网站上就能下载到,无非就是花一页纸吹了一下自己这个芯片有如何如何的 feature 云云,然后再花了一页纸作 Overview,扔一个架构图上去完事儿,真是印证了 Brief 这个词。

后来我才从某个网页上无意得知,Broadcom 的 Datasheet 一般是不公开的。只在有渠道的代理商那儿有,只有从人家那儿拿货然后签订一个保密协议,人家才会给你一份 PDF 文档。当然给你的文档是没法传播的:每一页纸上面都斜贯着长长的一串水印——谁泄露出去了谁承担责任。Broadcom 这招的确狠,可也给 bugfix 工作设置了最大的屏障。

针对这个 bug 给出解决方案的是 Jouke Witteveen。他的解决方案没有去 patch OpenWRT,而是给 wpa_supplicant 上的 wired Driver 作出了修正。他提出了一个新的 roboswitch driver 专门用于 Roboswitch 上的 802.1X 认证。我现在寝室里用的 Buffalo WHR-HP-G54 上就使用此程序通过了学校的 802.1X 认证。然后再运行一个 mytunet 来打开网关上的出校访问权限。这样就可以在全天时间使用无线网络了。(熄灯停电时除外……)

这个 bugfix 我用了大半年了,还是比较顺利的。只是最近在恩山无线论坛上看到了很多人受困于 H3C 和锐捷的私有 802.1X 认证。于是有人打算在路由器上运行 Linux 版的认证程序从而通过校园网认证。无奈的是这个 bug 再一次阻止了一大部分人的企图…… 很多人新买的路由器比如 WHR-HP-G54、WL-520gU、WHR-G125 等都有 roboswitch 的身影,移植过来的认证程序在 PC 上跑跑当然可以,可惜是没有针对性地解决 Broadcom roboswitch 的问题。自然也逃不过此 bug 的追杀,恩山上铩羽而归的人不在少数。

幸运一些的人有两种可能。一种是使用的 Belkin 7231-4p(不管有没有经过恩山无线的改版)它使用了 ADM6996L 交换芯片,没有此问题。另外一种是像 felix021 同学那样的,虽然路由器是使用 BCM5354 芯片的 WL-520gU,但校园网认证协议使用广播包(MAC为 FF-FF-FF-FF-FF-FF)而不是多播包。所有的交换模块接到了广播包当然是无条件转发。因此也能顺利通过认证。

不幸运的该怎么办呢? 😈  可以移植 Jouke Witteveen 在 roboswitch 中使用过的方法,在私有协议的认证程序中加入 Broadcom 芯片的支持,则有希望通过认证了。我已经跟 Jouke Witteveen 取得联系,他毫无保留地提供了一份 leaked document 给我作参考,十分感谢。 🙂

PS: 发现 WordPress 链接到自己文章的时候会发送 pingback,看上去真傻……只好装了一个 No-self-ping 插件。

开源路由器固件上 Bug 的故事(一)

前段时间在 atppp 的博客上读到了“纪念一个 Bug”,这让我想起了 OpenWRT 开源固件上面关于 Broadcom 交换芯片的一个 bug,所以也来写个文章纪念一下。

1. Linksys 开源路由器固件的起源和发展

OpenWRT 这个项目最早起源于 Linksys 的 WRT54G 家用无线路由器固件。WRT54G 这款无线路由器(台灣同胞稱作“無線基地台”或者“無線IP分享器”)是 2003 年 802.11g 无线网络兴起时在家用领域的领军人物,引来叫好一片。于是有人研究了它的软件系统,赫然发现它是一个基于 Linux 的嵌入式系统。所以根据 GPL 这一个病毒一样的协议要求 Linksys 开放源代码。Linksys 架不住压力,于是根据 GPL 开放了源代码(现在还可以在 Linksys 的网站上下载)。这一开放,就使得第三方固件雨后春笋一般蓬勃发展起来。OpenWRT 是最特别的一个。因为别家都是在 Linksys 的源代码基础上添砖加瓦,唯有 OpenWRT 是重新构造一个完整功能的路由器固件。

然而做 OpenWRT 的都是一群高人,他们注重扩展性、可定制性却忽视了普通大众的需求。做出来的东西只能用命令行玩玩,这让习惯从浏览器里配置无线路由器的劳苦大众无所适从。所以后来有了 Seavsoft 做了收费但带有 Web UI 的固件,再后来又有了 DD-WRT,DD-WRT 从 v23 的成熟发展到今天 v24 sp2 的功能多样而不失易用性,的确为开源无线路由器的发展立下了汗马功劳。

Tomato 是 DD-WRT 之外异军突起的一个优秀固件。它注重于简单、实用、高效,并且以优雅的 AJAX Web UI 和高效的 QoS 功能赢得了广泛支持。作者原来是 HyperWRT 开发小组的一员,后来跑出来自立门户开发 HyperWRT + Tofu 固件,就演变成了今天的 Tomato Firmware 。

(汗 :mrgreen: 说了个背景就说了这么多!)

2. 关于 802.1X 认证的 bug

因为面向家用和小企业市场,家用路由器的连接方式主要是 PPPoE 和 LAN 接入。但是现在众多学校等接入单位觉得对于 LAN 接入不方便对用户的控制和管理,于是把原本为无线网络设计的 802.1X 认证体系引入到了 LAN 网络中。802.1X 是一个二层的访问控制协议,用户只有认证之后,交换机才开放相应的端口,允许用户接入。这就是传说中的“基于端口”的管理。

众多学校引入了 IEEE 802.1X 之后,导致市面上的家用无线路由统统作废,因为这些设备压根就没有支持 802.1X 这回事(当然现在国内的 TP-LINK 已经顺应国情推出了支持 802.1X 认证的产品)。更可恶的是,国内的锐捷、H3C 推出了802.1x 的自有扩展协议,只能使用自己研制的客户端上网。而这些客户端无一例外地“附赠”了禁止NAT、多网卡的功能。妄图以多角度、多手段来扼杀同学们突破限制的种种企图。

俗话说“道高一尺,魔高一丈”,又说“上有政策,下有对策”,Linux 版本的 802.1x 客户端也自然而然的产生了。而开源固件又正好是基于 Linux 制作的。这些小路由器们个个都有支持 MIPS 指令集的 CPU,外加 4-32 MB 不等的 Flash ROM 和 RAM,本身就是一个五脏俱全的嵌入式 Linux 系统。这样就可以想办法将认证程序移植到开源固件中。

我去买了个 Buffalo  WHR-G125 ,在 Ubuntu Linux 下半生不熟地用交叉编译工具编译出学校校园网的认证程序 mytunet,满怀希望地放上去跑,没想到程序一直停滞在“Send logon request …” 这一步,压根没有收到服务器的响应。但把网线换到 PC 上又可以正常登录。看来是某个地方有问题了。

后来在 Google 上使劲搜,终于找到了问题的原因,OpenWRT 的 Trac 上有两个编号为 16871862 的 Ticket 说明了这个问题。

1687 放出来以后,人家没仔细看就把这个 ticket 关掉了,后面又有人 reopen ,然后再度被关闭。如此往复了几次,就晾在那没人理了。

1862 就更无奈了,Bug 放出来一年没有人理,四楼的哥们一怒之下来了一段抱怨的话:

Judging the fact that this bug is now lingering on for more than a year (since I first pointed it out) and the zero respons from the openwrt team, I came to the understanding that the openwrt team is more interested in fancy apps than a good working tcp stack. Shame shame shame.

俺七个月以前看到这个状态的时候,也觉得很无奈。人家开发者压根不鸟你,只好自己也参与讨论,然后以 Scott Liu 的身份在上面用蹩脚的英语提了提自己的意见完事。

后来把这个路由器在水木二手版上折价买掉了,360买回来的东西拿回来没过十天转出去的时候就是 260 了,价格掉得真快。期间有幸得到康神的指导,倍感荣幸。神说俺体察了一下网络上的民情,发现这是 Broadcom 交换芯片的硬伤,只是俺精力不如从前没工夫去 patch 了,你把它出掉是明智的。神又给我指了一条明路,说神自己的 Dell TrueMobile 2300 可以发送和接收 EAP 认证包,不存在上面的问题,指示我去买一个使用了 6996L 交换芯片的机器就没问题。

幸得神助,又在淘宝上淘了一个 Linksys WRT54GS v1.1 v1.0 (感谢 hyspace 指正) ,序列号以 CGN1 开头,特意跟店家确认了是 6996L 交换芯片。拿回来刷好固件,试了试,果然毫无问题地通过了校园 802.1X 认证!回来跟康神报告,神 cong 了一下又很谦虚地说“其实原因你自己之前也说了……”云云。向 atppp 学习随时随地拜康神!

买到了没有 bug 的硬件,这个问题基本上靠以段落了。下一段的 bugfix 又是后话。

AdSense成功申请经验谈

我从今年2月份开始申请 AdSense 至今,总算是在前两天批下来了。在这申请的过程之中,被拒过五六次,每一次被拒都能总结出一点经验来。所以申请成功了,也写一篇文章出来总结一下。

之前我已经写过一篇文章《Google Adsense申请依然被拒及其总结》,在那篇文章里已经差不多把 Google Adsense 申请的经验总结出来了。这一次的申请成功只是对它的一种验证。

依前文所言,AdSense 的申请虽然最终是由人工来批准。但是在这个申请之前会有一个严格的机器检查的过程,如果有不符合的地方,就会按照问题类型自动给你发一封拒信。

那么这个机器检查的依据是什么呢?从我申请的经验总结看来,我认为是 Google Webmaster Tools 中的统计数据。最初我申请被拒,有一个很重要的原因是我的博客从 Blogger 搬独立的 WordPress 主机上之后,文章的链接地址已经变了(我没有做重定向),所以之前被 Google 抓取的那些链接也都失效了!结果就是我从 Google Webmaster Tools 中看到一大堆错误。包括“Errors for URL in sitemaps”、“Not found”、“Not Followed”,加起来总共有几百之多。

当时我没有意识到这个,再次提交了自己的申请,结果拒信也来得很快。而且提示理由是“正在建设中”。囧!明明我的 WordPress  博客站点正常运转,却要被认为是正在建设中。我这才意识到极有可能是 Webmaster Tools 中的统计数据给 Google 造成了误判断。

下面的努力就是让 Google 消除这些错误了。但是以通常情况来看,Google 的索引通常更新得很慢(官方说要一个月到三个月左右),况且网上还有一些链接指向了我原来的博客文章,等 Google 自己消除这些错误信息的统计数据总不是个办法。只好出一个下策,编写了一个 Robots.txt 文件,放到网站的根目录。好在各大搜索引擎在 Robots.txt 面前还是比较老实的。我设置了规则,不让搜索引擎访问之前已经失效的地址。这样,原来的“Not found”等类型的错误就被归到“URL restricted by robots.txt”,在 Google 那里这个类型的提示是不算错误的。所以可行。

又等了几周,到四月份了,我的域名也正好注册了六个月,满足了 Google 之前放出的“网站注册满六个月”的要求(有人说不是特别严格)。眼看 Webmaster Tools 中统计的错误信息归零了,我就再次提交了申请。果然周末一过,周一中午我就收到了通知信,告诉我申请已经被批准,算是成功了。

写这篇文章主要是在 Adsense 愈来愈难申请的现在作出一个总结,给后来申请失败的人留作一个参考吧。我总结出来的要点就是:

  1. 满足 Adsense 对网站类型、内容等的基本要求;(废话,这是基本要求了 😳 )
  2. 网站在 Google 中有足够的索引;这一个可以在 Google 中用“site”语法来搜索,比如搜索我的域名就是“site:xiaoding.org”,返回的结果就是索引的数目;(这个也不难做到,向 Google 提交自己的网站,等几天就有了 🙂 )
  3. 网站在 Google Webmaster Tools 中不能有过多的统计错误。这一条我认为是最重要的!Google 可能是以机器的方式来判断,所以在机器面前务必达到这个要求。具体的阀值是多少我不清楚,最好是零。(如果有错误的话,可以考虑用 Robots.txt 把那些有错误的网址设为禁止,这样不久统计信息就能归零了)

这几条都做到了,大抵就没有问题了,Enjoy! 😎

庄生不幸而吾生幸:听陈怡老师讲庄子

第八周将尽,还有半个学期就要毕业。好在这四年来我终于听了一堂令我甘之如怡的课,始令我觉得这四年总算没有白过。这便是听东南大学的陈怡老师讲庄子。(这课亦是我编写了一个选课的计算机程序,以“非法”手段选中的。 😎 )

援引陈怡老师的一段介绍如下:

陈怡教授来自有着浓厚理工科背景的东南大学,他的专业是电机,并曾任东南大学教务长多年。在专业领域取得骄人成绩的同时, 陈怡教授以承传先人的经典智慧为己任,致力于传统文化的弘扬,尤其对老庄思想有深入研究,在各地高校做过几十次演讲,佳评如潮。现任《中国大学教学》主编。

陈老师是东南大学的教授,此番于清华来讲课是为客座,另有历史系的程钢老师和一帮博士生作为助教。陈老师在介绍自己的时候说“我是搞电气工程出身的”,让我们一帮学生大为惊异。以凡人的眼光看来,老庄这样最深邃的哲学研究居然由一位理工科出身的老师来教授,也许难以服人。但是陈老师用旁征博引、精彩幽默的生动讲授化解了所有人的疑问。

由于时间的限制,这门课程一共只有八次课,此外有三堂课外的讨论课,可以供同学们自由发言。陈老师很自然地用第一堂课介绍了自己和庄子,然后借用庄子中的一些易懂的寓言故事来阐述庄子的思想和观念。后七次课则分七次讲授了《庄子》的内七篇:《逍遥游》、《齐物论》、《养生主》、《人间世》、《德充符》、《大宗师》和《应帝王》。

《庄子》的内七篇据后人考证应为庄子本人所作,外篇和杂篇则是庄子门生所托。所以老师也恰当地选择了内七篇来介绍了最真实的庄子思想。况且读懂内七篇之后,便能顺着脉络去读外篇和杂篇。由此我也很佩服陈老师在短短的八周时间里所作的安排。

课程在上周二结束。现在若非要我说点东西出来,则似乎忘掉的比记得的多,很多理解都在书本上,八周的时间要深入其里也并不容易。现在好像是一种“见山不是山,见水不是水”的感觉。只知道那七篇文章的总体架构如何。既然我也说不清,还是借用老师的精辟总结阐述一番吧。

逍遥游:人生观,高远超越的逍遥人生;
齐物论:世界观,道通为一的博大情怀;
养生主:生命观,薪尽火传的养生主旨;
人间世:处世观,艰难时代的处世智慧;
德充符:道德观,形有所忘的德充标志;
大宗师:生死观,死生如一的宗师境界;
应帝王:政治观,用心若镜的帝王方略。

庄子生活在礼崩乐下,大道不存,战乱频繁的黑暗时代,正是因为庄子看透了世间的纷争,世道的不幸,所以才著书尽言,所以说是时代的不幸造就了庄子的有幸。而正是庄子所处的不幸造就了今人之有幸,使人们在数千年以后,仍然能接触到这样博大精深又汪洋恣意的独特思想。庄子没有告诫人们要“成仁取义”,也没有给予那种“虽千万人吾往矣”的勇气。但是他却传授了为人处世的大智慧,无所不容人皆可以各取所需,这种智慧就像根一样深深地扎在每一个中国人的心底。

iPhone/iPod Touch上的读书字体

在 iPhone/iPod Touch 上看电子书估计也是大多数人的需求之一。我买来这个就是看重它的大屏幕和 Wi-Fi 连接功能,游戏和触摸屏对我来说倒是次要的。

但是对于我这样 detail focus 的人来说,iPod Touch 上的字体却是很难让人满意的。苹果只给带了一个 STHeiti,虽然看看网页什么的这个字体已经够了。但是长时间的阅读如果看着黑体字的话会非常别扭。因为黑体字属于“无衬线字体”(Sans-serif),而宋体字属于“有衬线字体”(Serif),后者对于人眼的辨识来说会更轻松一些,所以阅读的时候会比较舒服。(关于这两种字体的区别和特点可以去 Google 上搜索,在此推荐阅读 http://yx.takeback.net/121/serif-font.html )

之前 chumsdock 同学也发现了这一点,在他的解决方案中给系统中装了一个 STSong 字体。我最初是采用的这个解决方案。但后来在阅读某些繁体字作品的时候发现系统对于繁体字的显示还是不正常,可能是 STSong 里面没有包含繁体字体信息,所以导致简繁二者混合起来显示,效果就惨不忍睹了。 😥

没办法,书是要读的,问题也需要解决。为此我详细地搜索了一下如何给 iPhone/iPod Touch 上添加多余的字体,然而找到的文章多数是采用替换大法,将原有的系统字体文件替换掉,而不是新添加某种字体。这不符合我的需要。想了想,决定还是自己先尝试一番为妙。

chumsdock 说他已经试过系统自带的几种字体了,然而除 STSong 之外无一成功,所以我也就不必多费气力了。把目光转到 Adobe Acrobat 上面,这个东东是自带某些 Adobe 家的字体的。于是在 C:Program FilesAdobeAcrobat 8.0ResourceCIDFont 这个路径下找到了 Adobe Acrobat(Adobe Reader 貌似也有)中的几个字体,其中有一个“Adobe 宋体 Std Light”,这个可以拿来一试。于是照猫画虎地把字体拷到 iPod 文件系统中,然后拿 pledit 把 plist 文件修改一下,字体名称用“AdobeSongStd-Light”,放到系统中去替换原文件。再重启一下,果然可以用,放两张图上来(图片已失效)。