分类 wifidog安装 下的文章

wifidog源码分析 - wifidog原理

wifidog是一个用于配合认证服务器实现无线网页认证功能的程序,常见的情景就是使用于公共场合的无线wifi接入点,首先移动设备会连接公共wifi接入点,之后会弹出网页要求输入用户名密码,认证过后才能够连入外网。其主页是http://dev.wifidog.org/
实现原理
  其实wifidog原理很简单,主要是通过管控iptables,配合认证服务器进行客户端的放行操作。wifidog在启动后都会自动启动三个线程,分别为客户端检测线程、wdctrl交互线程、认证服务器心跳检测线程。每当新用户连接无线AP并浏览网页时,wifidog会获取新用户的此次操作,并返回一个重定向到认证服务器的http于用户,此后用户通过认证服务器认证后,再继续浏览网页时,wifidog会询问认证服务器此用户权限,若放行则修改iptables放行此用户IP。

1)主要流程如下
添加关键路径对应的回调函数
删除所有iptables路由表
建立新的iptables路由表
开启客户端检测线程(用于判断客户端是否在线,是否登出)
开启wdctrl交互线程
开启认证服务器心跳检测线程
循环等待客户端连接(使用socket绑定2060端口并监听,实际上在建立新的iptables路由表规则时会将网关的80端口重定向到2060端口)

2)回调函数
  回调函数主要用于根据用户http报文执行不同的操作,其原理就是分析http报文请求中有没有关键路径,若有,则执行关键路径对应的回调函数,若没有,则返回一个重定向到认证服务器的包给用户。一次典型的流程为

用户连接无线AP,访问某网站(比如http://www.baidu.com
wifidog获取到此http报文,检查是否包含关键路径,没有则返回重定向包给用户,将其重定向到认证服务器
用户认证成功,认证服务器将用户重定向到无线AP网关,并包含关键路径"/wifidog/auth"和token
wifidog接收到用户重定向后访问的报文,检测到关键路径"/wifidog/auth",然后访问认证服务器进行token认证
认证成功,wifidog修改iptables放行此用户(根据mac和ip进行放行)

3)wifidog的iptables规则
  这一部分我没有仔细认真看源码,但可以推论出wifidog是怎么修改iptables的规则的,了解iptables基本原理的同学都清楚iptables实际上有两条路进行数据包处理,一条路会通过应用程序,一条路不同过应用程序,直接到POSTOUTPUT,而我认为wifidog建立的规则是

只要是访问认证服务器的http请求都直接不通过wifidog发送出去
只要是通过认证的客户端wifidog都会修改iptables让其数据直接从FORWARD到POSTOUTPUT,而不经过wifidog
其他行为都必须进过wifidog处理

4)客户端检测线程
  此线程每隔60s会遍历一次客户端列表,对每一个客户端列表统计流量,如果客户端在60s间隔内没有新产生的流量则不更新客户端的最新更新时间,当当前时间减去最新更新时间大于断线要求时间时,则会将此客户端从客户端列表删除,并修改iptables规则禁止其访问外部网络,然后发送此客户端登出包于认证服务器,认证服务器根据此登出包将此客户端做登出处理。如若没有超出断线要求时间,此线程还会发送客户端状态获取包于认证服务器,认证服务器返回此客户端在认证服务器上的信息,如若信息表示此客户端已在认证服务器上登出,wifidog则会执行此客户端下线操作。

5)wdctrl交互线程
  其原理是使用unix socket进行进程间通信,具体实现在之后文章中体现

6)认证服务器心跳检测线程
  原理也很简单,就是每隔60s将路由的一些系统信息发送给认证服务器,认证服务器接收到会返回一个回执

7)循环等待客户端连接
  这里主要会接收到两种类型的客户端连接

未认证的客户端打开网页操作,wifidog会接收到此http请求,并返回一个重定向到认证服务器的包于客户端
经过认证服务器认证成功后,认证服务器自动将客户端重定向到无线AP的操作,wifidog接收到此类http请求后会检测关键路径"/tmp/wifidog",并把http请求中携带的token与认证服务器进行认证,认证成功后则修改iptables放行客户端。

具体代码实现见之后章节

本文章由 http://www.wifidog.pro/2015/02/02/wifidog%E5%8E%9F%E7%90%86.html 整理编辑,转载请注明出处

广告路由器开发(二)实践-wifidog版

上篇文章中分析了wifidog下authpuppy之间的数据流这篇文章中我就介绍一下如何书写一个简单的广告路由器
经过以上分析不难看出 实现一个广告路由器还是非常简单的
由于我本人对symfony框架不感冒 故以下示例代码使用了phalcon框架进行书写(只是演示用而已)

<?php  

namespace controllers;  

class InterfaceController extends \Phalcon\Mvc\Controller  
{  

    public function initialize( )  
    {  

    }  

    public function indexAction( )  
    {  
    }  

    public function loginAction( )  
    {  
        if( $this->request->isGet() && null == $this->request->getQuery( 'advs' ) )  
        {  
            $strDebug = var_export( $_SERVER, true );  

            $this->view->setVar( 'iRefreshTime', 10 ); //广告时间10秒  
            $this->view->setVar( 'url', $this->request->getServer( 'REQUEST_URI' ) . '&advs=advs' );  

            $this->view->pick( 'interface/advs' );//这里展示广告  
        }  
        else  
        {  
            $this->view->disable();  

            $strToken = sha1( rand() . time() );  
            $this->persistent->set( 'redirectUrl', $this->request->getQuery( 'url' ));  
            $this->response->redirect( 'http://' . $this->request->get( 'gw_address' ) . ':' . $this->request->get( 'gw_port' ) . '/wifidog/auth?token=' . $strToken, true );  
        }  

    }  

    public function logoutAction( )  
    {  
        echo 'Auth:0';  
    }  

    public function portalAction( )  
    {//广告过后在此函数内进行跳转  
        $this->view->disable();  
        if( null != $strUrl = $this->persistent->get( 'redirectUrl' ) )  
        {  
            $this->response->redirect( $strUrl, true );  
        }  
        else   
        {  
            $this->response->redirect( 'http://blog.csdn.net/qzfzz', true );  
        }  
    }  

    public function pingAction( )  
    {  
        echo 'Pong';  
    }  

    public function msgAction( )  
    {  
    }  

    public function authAction( )  
    {  
        echo 'Auth: 1';  
    }  

}  

以下为视图

<!--advs.phtml-->  
<!doctype html  
<html>  
<head>  
<meta http-equiv="refresh" content="<?php echo $iRefreshTime;?>;url=<?php echo $url;?>"/>  
<title>Login</title>  
</head>  
<body>  
<p>这里可以展示广告等信息</p>  
</body>  
</html> 

经过以上的开发一个简单的广告路由器即完成了

本文章由 http://www.wifidog.pro/2015/01/30/wifidog%E5%BC%80%E5%8F%91.html 整理编辑,转载请注明出处

广告路由器开发(一)数据流-wifidog版

最近无事时对广告路由器进行了一个分析
常用的广告路由器一般是通过普通路由器刷openwrt或是ddwrt等固件后安装wifidog组件做的,我们这里分析的即是wifidog加authpuppy
以下数据为截取自authpuppy和wifidog的交互

1.用户请求页面http://www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm  
--------------------------------------------------------------------------------------  
request:  
/login/?gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm  

response:  
<form action="http://192.168.1.251:81/login/?gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm" method="POST">  
    <input type="hidden" name="gw_id" value="default" />  
  <input type="hidden" name="gw_address" value="192.168.4.1" />  
  <input type="hidden" name="gw_port" value="2060" />  
        <input type="hidden" id="authenticators" name="authenticator" value="apAuthLocalUser"/>  
      <div id="authPlugin_apAuthLocalUser" style="display: none">  
            <h1>Local network user authentication</h1>  

                    <input type="submit" name="submit[apAuthLocalUserconnect]" id="submit[apAuthLocalUserconnect]" value="Connect" onClick="deleteLinkElement()" />  
                    <input type="password" name="apAuthLocalUser[password]" value="Pb4AoWdlOhqu4B2T535zDg==" id="apAuthLocalUser_password" />  
                    <label for="apAuthLocalUser_remember_me">Remember me</label>  
                    <input type="checkbox" name="apAuthLocalUser[remember_me]" value="1" checked="checked" id="apAuthLocalUser_remember_me" />  
</form>  

array (  
  'REDIRECT_STATUS' => '200',  
  'HTTP_HOST' => '192.168.1.251:81',  
  'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',  
  'HTTP_COOKIE' => 'authpuppy=usb6bslekske7ek5rlorknvf43; localUserCookie=226f362768d281ff14cf428fa3c3b8c87a6c4834',  
  'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10',  
  'HTTP_REFERER' => 'http://news.baidu.com/',  
  'SCRIPT_FILENAME' => 'F:/phpStudyAll/WWW/authpuppy/web/index.php',  
  'REMOTE_PORT' => '53961',  
  'REDIRECT_QUERY_STRING' => 'gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm',  
  'REDIRECT_URL' => '/login/',  
  'GATEWAY_INTERFACE' => 'CGI/1.1',  
  'SERVER_PROTOCOL' => 'HTTP/1.1',  
  'REQUEST_METHOD' => 'GET',  
  'QUERY_STRING' => 'gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm',  
  'REQUEST_URI' => '/login/?gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm',  
)  
++++++++++++++++++++++++++++++++++++++++++++++++  


2.登录成功以后而返回如下  
--------------------------------------------------------------------------------------  
request:  
/login/?gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm  

response:  
<html><head><meta http-equiv="refresh" content="0;url=http://192.168.4.1:2060/wifidog/auth?token=60bb7efe229270c4d6d36ed60bb5e98886900126"/></head></html>  

array (  
  'REDIRECT_STATUS' => '200',  
  'HTTP_HOST' => '192.168.1.251:81',  
  'CONTENT_TYPE' => 'application/x-www-form-urlencoded',  
  'HTTP_ORIGIN' => 'http://192.168.1.251:81',  
  'HTTP_COOKIE' => 'authpuppy=usb6bslekske7ek5rlorknvf43; localUserCookie=226f362768d281ff14cf428fa3c3b8c87a6c4834',  
  'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10',  
  'HTTP_REFERER' => 'http://192.168.1.251:81/login/?gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm',  
  'HTTP_ACCEPT_LANGUAGE' => 'en-us',  
  'HTTP_ACCEPT_ENCODING' => 'gzip, deflate',  
  'REMOTE_ADDR' => '192.168.1.106',  
  'REMOTE_PORT' => '53950',  
  'REDIRECT_QUERY_STRING' => 'gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm',  
  'REDIRECT_URL' => '/login/',  
  'GATEWAY_INTERFACE' => 'CGI/1.1',  
  'SERVER_PROTOCOL' => 'HTTP/1.1',  
  'REQUEST_METHOD' => 'POST',  
  'QUERY_STRING' => 'gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm',  
  'REQUEST_URI' => '/login/?gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm',  
  'REQUEST_TIME' => 1411547194,  
)  
++++++++++++++++++++++++++++++++++++++++++++++++  

3. 在2中进行跳转后则WiFiDog服务器向授权服务器端发送GET授权请求 若成功则而返回Auth: 1  
--------------------------------------------------------------------------------------  
request:  
/auth/?stage=login&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=0&outgoing=0&gw_id=default  

response://千万要注意这里Auth:与1之间有一个空格否则不能通过验证  
Auth: 1  

array (  
  'REDIRECT_STATUS' => '200',  
  'HTTP_USER_AGENT' => 'WiFiDog 20130917',  
  'HTTP_HOST' => '192.168.1.251',  
  'SERVER_PORT' => '81',  
  'REMOTE_ADDR' => '192.168.1.106',  
  'REMOTE_PORT' => '33264',  
  'REDIRECT_QUERY_STRING' => 'stage=login&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=0&outgoing=0&gw_id=default',  
  'REDIRECT_URL' => '/auth/',  
  'GATEWAY_INTERFACE' => 'CGI/1.1',  
  'SERVER_PROTOCOL' => 'HTTP/1.0',  
  'REQUEST_METHOD' => 'GET',  
  'QUERY_STRING' => 'stage=login&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=0&outgoing=0&gw_id=default',  
  'REQUEST_URI' => '/auth/?stage=login&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=0&outgoing=0&gw_id=default',  
  'REQUEST_TIME' => 1411547194,  
)  
++++++++++++++++++++++++++++++++++++++++++++++++  

4.WiFiDog在接收到Auth:1之后向服务器端发送/portal/?gw_id=default的GET请求 授权服务器返回立即跳转的页面如下:  
--------------------------------------------------------------------------------------  
request:  
/portal/?gw_id=default  

reponse:  
<html><head><meta http-equiv="refresh" content="0;url=http://www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm"/></head></html>  

array (  
  'REDIRECT_STATUS' => '200',  
  'HTTP_HOST' => '192.168.1.251:81',  
  'HTTP_ORIGIN' => 'http://192.168.1.251:81',  
  'HTTP_COOKIE' => 'authpuppy=usb6bslekske7ek5rlorknvf43; localUserCookie=226f362768d281ff14cf428fa3c3b8c87a6c4834',  
  'HTTP_CONNECTION' => 'keep-alive',  
  'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',  
  'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10',  
  'HTTP_ACCEPT_LANGUAGE' => 'en-us',  
  'HTTP_REFERER' => 'http://192.168.1.251:81/login/?gw_address=192.168.4.1&gw_port=2060&gw_id=default&mac=00:0e:c6:f0:06:b2&url=http%3A//www.gov.cn/guowuyuan/2014-09/23/content_2755108.htm',  
  'HTTP_ACCEPT_ENCODING' => 'gzip, deflate',  
  'REDIRECT_QUERY_STRING' => 'gw_id=default',  
  'REDIRECT_URL' => '/portal/',  
  'GATEWAY_INTERFACE' => 'CGI/1.1',  
  'SERVER_PROTOCOL' => 'HTTP/1.1',  
  'REQUEST_METHOD' => 'GET',  
  'QUERY_STRING' => 'gw_id=default',  
  'REQUEST_URI' => '/portal/?gw_id=default',  
  'SCRIPT_NAME' => '/index.php',  
  'PHP_SELF' => '/index.php',  
  'REQUEST_TIME' => 1411547194,  
)  
++++++++++++++++++++++++++++++++++++++++++++++++  

5.WiFiDog服务器向授权服务器发送ping操作请求 服务器端通过后发送Pong响应串(纯文本)  
--------------------------------------------------------------------------------------  
request:  
/ping/?gw_id=default&sys_uptime=28824&sys_memfree=99284&sys_load=0.08&wifidog_uptime=61  

response:  
Pong  


array (  
  'REDIRECT_STATUS' => '200',  
  'HTTP_USER_AGENT' => 'WiFiDog 20130917',  
  'HTTP_HOST' => '192.168.1.251',  
  'SERVER_SIGNATURE' => '',  
  'SERVER_SOFTWARE' => 'Apache/2.4.9 (Win32) OpenSSL/0.9.8y PHP/5.3.28',  
  'SERVER_NAME' => '192.168.1.251',  
  'SERVER_ADDR' => '192.168.1.251',  
  'SERVER_PORT' => '81',  
  'REMOTE_ADDR' => '192.168.1.106',  
  'DOCUMENT_ROOT' => 'F:/phpStudyAll/WWW/authpuppy/web',  
  'REQUEST_SCHEME' => 'http',  
  'CONTEXT_PREFIX' => '',  
  'CONTEXT_DOCUMENT_ROOT' => 'F:/phpStudyAll/WWW/authpuppy/web',  
  'SERVER_ADMIN' => 'admin@phpStudy.net',  
  'SCRIPT_FILENAME' => 'F:/phpStudyAll/WWW/authpuppy/web/index.php',  
  'REMOTE_PORT' => '33265',  
  'REDIRECT_QUERY_STRING' => 'gw_id=default&sys_uptime=28824&sys_memfree=99284&sys_load=0.08&wifidog_uptime=61',  
  'REDIRECT_URL' => '/ping/',  
  'GATEWAY_INTERFACE' => 'CGI/1.1',  
  'SERVER_PROTOCOL' => 'HTTP/1.0',  
  'REQUEST_METHOD' => 'GET',  
  'QUERY_STRING' => 'gw_id=default&sys_uptime=28824&sys_memfree=99284&sys_load=0.08&wifidog_uptime=61',  
  'REQUEST_URI' => '/ping/?gw_id=default&sys_uptime=28824&sys_memfree=99284&sys_load=0.08&wifidog_uptime=61',  
  'SCRIPT_NAME' => '/index.php',  
  'PHP_SELF' => '/index.php',  
  'REQUEST_TIME' => 1411547224,  
)  
++++++++++++++++++++++++++++++++++++++++++++++++  

6.WiFiDog向服务器发送计费通知  
--------------------------------------------------------------------------------------  

request:  
/auth/?stage=counters&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=4660796&outgoing=192338&gw_id=default  

response:  
Auth: 1//中间一定要有一个空格  

array (  
  'REDIRECT_STATUS' => '200',  
  'HTTP_USER_AGENT' => 'WiFiDog 20130917',  
  'HTTP_HOST' => '192.168.1.251',  
  'SERVER_NAME' => '192.168.1.251',  
  'SERVER_ADDR' => '192.168.1.251',  
  'SERVER_PORT' => '81',  
  'REMOTE_ADDR' => '192.168.1.106',  
  'REMOTE_PORT' => '33266',  
  'REDIRECT_QUERY_STRING' => 'stage=counters&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=4660796&outgoing=192338&gw_id=default',  
  'REDIRECT_URL' => '/auth/',  
  'GATEWAY_INTERFACE' => 'CGI/1.1',  
  'SERVER_PROTOCOL' => 'HTTP/1.0',  
  'REQUEST_METHOD' => 'GET',  
  'QUERY_STRING' => 'stage=counters&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=4660796&outgoing=192338&gw_id=default',  
  'REQUEST_URI' => '/auth/?stage=counters&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=4660796&outgoing=192338&gw_id=default'  
)  
++++++++++++++++++++++++++++++++++++++++++++++++  

7.退出登录  
--------------------------------------------------------------------------------------  

request:  
/auth/?stage=logout&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=0&outgoing=0&gw_id=default  

response:  
Auth: 0  

array (  
  'REDIRECT_STATUS' => '200',  
  'HTTP_USER_AGENT' => 'WiFiDog 20130917',  
  'HTTP_HOST' => '192.168.1.251',  
  'SERVER_NAME' => '192.168.1.251',  
  'SERVER_ADDR' => '192.168.1.251',  
  'SERVER_PORT' => '81',  
  'REMOTE_ADDR' => '192.168.1.106',  
  'REQUEST_SCHEME' => 'http',  
  'CONTEXT_PREFIX' => '','stage=logout&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=0&outgoing=0&gw_id=default',  
  'REDIRECT_URL' => '/auth/',  
  'GATEWAY_INTERFACE' => 'CGI/1.1',  
  'SERVER_PROTOCOL' => 'HTTP/1.0',  
  'REQUEST_METHOD' => 'GET',  
  'QUERY_STRING' => 'stage=logout&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=0&outgoing=0&gw_id=default',  
  'REQUEST_URI' => '/auth/?stage=logout&ip=192.168.4.186&mac=00:0e:c6:f0:06:b2&token=60bb7efe229270c4d6d36ed60bb5e98886900126&incoming=0&outgoing=0&gw_id=default',  
  'SCRIPT_NAME' => '/index.php',  
  'PHP_SELF' => '/index.php',  
  'REQUEST_TIME' => 1411549984,  
)  
++++++++++++++++++++++++++++++++++++++++++++++++  

本文章由 http://www.wifidog.pro/2015/01/30/wifidog%E6%95%B0%E6%8D%AE%E6%B5%81.html 整理编辑,转载请注明出处

OpenWRT 增加内核模块及应用方法

进入package目录,创建模块目录
cd mcp/branches/V1.1-beta1/mcp/package
mkdir example
进入example目录,创建Makefile文件和代码路径

cd example
touch Makefile
mkdir src

Makefile具体内容如下:

# Kernel module example
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=example
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk

define KernelPackage/example
  SUBMENU:=Other modules
  DEPENDS:=@TARGET_octeon
  TITLE:=Support Module for example
  AUTOLOAD:=$(call AutoLoad,81,example)
  FILES:=$(PKG_BUILD_DIR)/example/example.$(LINUX_KMOD_SUFFIX)
endef

define Build/Prepare
  mkdir -p $(PKG_BUILD_DIR)
  $(CP) -R ./src/* $(PKG_BUILD_DIR)/
endef

define Build/Compile
  $(MAKE) -C "$(LINUX_DIR)" \
    CROSS_COMPILE="$(TARGET_CROSS)" \
    ARCH="$(LINUX_KARCH)" \
    SUBDIRS="$(PKG_BUILD_DIR)/example" \
    EXTRA_CFLAGS="-g $(BUILDFLAGS)" \
    modules
endef

$(eval $(call KernelPackage,example))

进入src目录,创建代码路径和相关源文件

cd src
mkdir example
cd example
touch example.c Kconfig Makefile

example.c具体内容如下:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

/* hello_init ---- 初始化函数,当模块装载时被调用,如果成功装载返回0 否则返回非0值 */
static int __init hello_init(void)
{
   printk("I bear a charmed life.\n");
   return 0;
}

/ * hello_exit ---- 退出函数,当模块卸载时被调用 */
static void __exit hello_exit(void)
{
   printk("Out, out, brief candle\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhangjiefeng");

Kconfig具体内容如下:

config EXAMPLE
  tristate "Just a example"
  default n
  help
   This is a example, for debugging kernel model.
   If unsure, say N.

Makefile具体内如如下:

obj-m := example.o

回到主路径 mcp/branches/V1.1-beta1/mcp/,编译选项配置保存并编译

make menuconfig
  Kernel modules --->
    Other modules --->
      kmod-example

选项设置为M,保存退出
  然后编译该模块:

make package/example/compile

编译出的文件可以在主路径的以下路径找到

./staging_dir/target-mips64_eglibc-2.10.1/root-octeon/lib/modules/2.6.30.9/
./build_dir/linux-octeon/example/ipkg-octeon/kmod-example/lib/modules/2.6.30.9/
./build_dir/linux-octeon/example/example/

文件名为:example.ko
  注:我们使用./build_dir/linux-octeon/example/example/example.ko

用户态工具添加方法
进入package目录,创建工具目录

cd mcp/branches/V1.1-beta1/mcp/package
mkdir example1

进入example1目录,创建Makefile文件和代码路径

cd example1
touch Makefile
mkdir src
 该Makefile具体内容如下:
#User mode tool example
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=example1
PKG_RELEASE:=1
PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk

define Package/example1
 SECTION:=utils
 CATEGORY:=Base system
 TITLE:=Build for example1 commands
endef

define Package/example1/description
 This package contains an utility useful to use example1 commands.
endef

define Build/Prepare
  mkdir -p $(PKG_BUILD_DIR)
  $(CP) ./src/* $(PKG_BUILD_DIR)/
endef

target=$(firstword $(subst -, ,$(BOARD)))
MAKE_FLAGS += TARGET="$(target)"
TARGET_CFLAGS += -Dtarget_$(target)=1 -Wall

define Build/example1/compile
  $(MAKE) -C "$(LINUX_DIR)" \
   CROSS_COMPILE="$(TARGET_CROSS)" \
   ARCH="$(LINUX_KARCH)" \
   SUBDIRS="$(PKG_BUILD_DIR)" \
   EXTRA_CFLAGS="$(BUILDFLAGS)"
endef

define Package/example1/install
  $(INSTALL_DIR) $(1)/sbin
  $(INSTALL_BIN) $(PKG_BUILD_DIR)/example1 $(1)/sbin/
endef

$(eval $(call BuildPackage,example1))

进入src目录,创建相关源文件

cd src
touch example1.c Makefile

example1.c 具体内容如下:

#include <stdio.h>
int main(void)
{
  printf("Hello, world\n");
  return 0;
}

Makefile文件具体内容如下:

.NOTPARALLEL:
#OCTEON_ROOT=$(PWD)/src/
CC=~/openwrt/main/staging_dir/toolchain-mips64_gcc-4.4.1_eglibc-2.10.1/usr/bin/mips64-openwrt-linux-gnu-gcc
CFLAGS=-mips64r2 -mabi=64 -march=octeon -mtune=octeon
LFLAGS=
.PHONY: all
all: example1
example1:example1.c
  ${CC} ${CFLAGS} ${LFLAGS} -W -g -Wall -Wno-unused-parameter -DUSE_RUNTIME_MODEL_CHECKS=1 \
    -o $@ example1.c

回到主路径 mcp/branches/V1.1-beta1/mcp/,编译选项配置保存并编译

make menuconfig
  Base system --->
   example1

选项设置为M,保存退出
然后编译该模块:

make package/example1/compile

编译出的文件可以在主路径的以下路径找到

./staging_dir/target-mips64_eglibc-2.10.1/root-octeon/sbin/
./build_dir/linux-octeon/example1/ipkg-octeon/example1/sbin/
./build_dir/linux-octeon/example1/

文件名为:example1
注:我们使用./build_dir/linux-octeon/example1/example1
根据OpenWrt安装介绍,将内核模块和用户态工具在板子上运行,到这就简单了往下我就不贴了。

本文章由 http://www.wifidog.pro/2015/01/30/openwrt%E6%B7%BB%E5%8A%A0%E6%A8%A1%E5%9D%97.html 整理编辑,转载请注明出处