├── README.md
├── accept.php
├── admin.php
├── data.json
├── filter.txt
├── index.js
├── index.php
├── mystyle.css
├── screen.png
├── showJs.php
└── wrtbwmon
/README.md:
--------------------------------------------------------------------------------
1 | ## 路由流量监控管理平台
2 |
3 | 
4 | ### What
5 | 路由流量监控管理平台是为了方便网络管理人员监控流量而做的一套基于openwrt的软件。
6 | 由后端shell脚本和前端web系统两部分组成。
7 | 后端shell脚本起到监控流量、同步mac白名单的作用。
8 | 前端web起到方便网络管理人员管理用户mac设备及用户流量的作用。
9 |
10 | ### Why
11 | 在网络流量有限,而连接用户未知的情况下,总是会经常出现流量超用滥用的情况。
12 | 在西电(当然诸如此类的网络环境应该还有很多),大多实验室、宿舍为了方便上网,都会采用openwrt的路由。
13 | 而在这套精简版的路由上面,并没有好的流量监控管理软件。
14 | 作者所在的活动室就处于这种情况的困扰,因此趁着这次比赛,实现了一个轻量级的流量监控管理系统
15 |
16 | ### Where
17 | * 平台:
18 | - OpenWrt 一款为路由定制的精简版Linux
19 | * 组件:
20 | - iptable Linux下最强大的防火墙,没有之一(自带)
21 | - /etc/config/wireless Openwrt下的MAC过滤配置文件(自带)
22 | - cron Linux下的定时管理任务守护进程(自带)
23 | Cron Config:
24 | * * * * * /bin/wrtbwmon setup br-lan
25 | * * * * * /bin/wrtbwmon update
26 | 3 1 1 * * /bin/wrtbwmon clear
27 | - uhttpd Openwrt下的web服务器 (opkg install uhttpd)
28 | - php5 php解析器 (opkg install php5)
29 | - php5-mod-json php的json处理模块 (opkg install php5-mod-json)
30 |
31 |
32 | ### How
33 | 在开发前,我们找到了wrtbwmon这个脚本,一个运行在Openwrt上的利用iptable进行流量统计的shell脚本。
34 | 在理解了wrtbwmon的工作机制之后,我们定义了一个json文件,结构参见文件data.json,作为该软件的数据结构。
35 | 我们hack了wrtbwmon的setup功能,实现了通过filter.txt实现内网流量的过滤。
36 | 我们hack了wrbwmon的update功能,将其输出按照我们定义的格式输入到data.json。
37 | 实现了sync的功能,对于data.json的未超流量的Mac地址同步到data.json。
38 | 实现了clear的功能,将data.json以日期备份然后将流量清零。
39 | 最后,我们实现一套web管理系统,便于管理员操作,实现用户和设备的增删改操作,并且触发后端的脚本进行同步。
40 |
41 | ### Who
42 | 西安电子科技大学 计算机学院 袁少鹏
43 | 西安电子科技大学 计算机学院 曾少剑
44 | 如果在使用中有任何问题,请email至ibirdyuan@gmail.com
45 |
46 |
47 |
--------------------------------------------------------------------------------
/accept.php:
--------------------------------------------------------------------------------
1 |
152 |
--------------------------------------------------------------------------------
/admin.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/data.json:
--------------------------------------------------------------------------------
1 | {"club":[
2 | {"name":"\u5415\u4e2d","total":"3221225472","nowflow":"0","device":[{"type":"kindle","mac":"ae:23:3a:4a:43:21","in":"0","out":"0"},{"type":"pc","mac":"12:12:12:11:11:11","in":"0","out":"0"}]},
3 | {"name":"\u738b\u4e39\u840c","total":"3221225472","nowflow":"0","device":[{"type":"pc","mac":"00:11:dd:23:e1:aa","in":"0","out":"0"}]}]}
--------------------------------------------------------------------------------
/filter.txt:
--------------------------------------------------------------------------------
1 | 202.117.112.0/20
2 | 210.27.0.0/20
3 | 219.245.64.0/18
4 | 115.155.0.0/18
5 | 222.25.128.0/18
6 | 219.244.112.0/20
7 | 10.168.200.1
8 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var typeArr = ['pc', 'kindle', 'phone', 'laptop', 'others']
2 | var flowArr = ['1','2','3','4','5']
3 | var Ajax_URL = '/FControl/accept.php'
4 | var flag = 1
5 |
6 | //初始化select标签,参数为option的value值的数组
7 | var initSelect = function( arr )
8 | {
9 | var select = document.createElement('select')
10 | for(i in arr)
11 | {
12 | var option = document.createElement('option')
13 | option.setAttribute('value', arr[i])
14 | option.text = arr[i]
15 | select.appendChild(option)
16 | }
17 | return select
18 | }
19 |
20 | var checkMac = function(macaddr)
21 | {
22 | var patt = new RegExp('^([0-9a-f]{2}:){5}[0-9a-f]{2}$')
23 | return patt.test(macaddr)
24 | }
25 |
26 | var arrToStr = function(arr)
27 | {
28 | var str = ''
29 | for( x in arr )
30 | {
31 | str += x + '='
32 | str += arr[x] + '&'
33 | }
34 | str = str.slice(0,-1)
35 | return str
36 | }
37 |
38 | var checkFlag = function()
39 | {
40 | if (flag == 0)
41 | {
42 | alert('请确认执行完上一个操作!')
43 | return false
44 | }
45 |
46 | flag = 0
47 | return true
48 |
49 | }
50 |
51 | //ajax方法
52 | var ajax = function(url, f, string){
53 | var xml = (window.XMLHttpRequest) ? (new XMLHttpRequest()) : (new ActiveXObject("Micorsoft.XMLHttpRequest"));
54 | xml.onreadystatechange = function(){
55 | f(xml.responseText);
56 | }
57 |
58 | xml.open("POST",url,true);
59 | xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
60 | xml.send(string);
61 | }
62 |
63 | //替换节点
64 | var changeId = function(id, newtype)
65 | {
66 | var old = document.getElementById(id)
67 | if(old.firstChild != null)
68 | {
69 | old.removeChild(old.firstChild)
70 | }
71 | old.appendChild(newtype)
72 | }
73 |
74 | //新增设备
75 | var addDevice = function(obj)
76 | {
77 | if(!checkFlag())return;
78 |
79 | var id = obj.name
80 | var oldtype = id + '_newtype'
81 | var oldmac = id + '_newmac'
82 |
83 | arr = {'method':'addDevice','id':id, 'node':{'device':oldtype,'macaddr':oldmac}}
84 | changeId(oldtype, initSelect(typeArr))
85 |
86 | var input =document.createElement('input')
87 | input.setAttribute('type' , 'text')
88 |
89 | changeId(oldmac, input)
90 | obj.setAttribute('value','确定')
91 | obj.setAttribute('onclick','Submit(arr)')
92 | }
93 |
94 | //新增用户
95 | var addUser = function(obj)
96 | {
97 | if(!checkFlag())return;
98 |
99 | var input =document.createElement('input')
100 | input.setAttribute('type' , 'text')
101 | changeId('newname', input)
102 |
103 | changeId('newflow', initSelect(flowArr))
104 |
105 | arr = {'method':'addUser','node':{'name':'newname','total':'newflow'}}
106 |
107 | obj.setAttribute('value','确定')
108 | obj.setAttribute('onclick','Submit(arr)')
109 |
110 | }
111 | //更改流量
112 | var changeFlow = function(obj)
113 | {
114 | if(!checkFlag())return;
115 |
116 | id = obj.name
117 | oldflow = id + '_flow'
118 |
119 | arr = {'method':'changeFlow','id':id, 'node':{'flow':oldflow}}
120 |
121 | changeId(oldflow, initSelect(flowArr))
122 |
123 | obj.setAttribute('value','确定')
124 | obj.setAttribute('onclick','Submit(arr)')
125 | }
126 |
127 |
128 | //修改Mac
129 | var changeMac = function(obj)
130 | {
131 | if(!checkFlag())return;
132 |
133 | var id = obj.name
134 | var oldmac = id + '_mac'
135 | var oldtype = id + '_type'
136 |
137 | arr = {'method':'changeMac','id':id, 'node':{'macaddr':oldmac}}
138 |
139 | var input =document.createElement('input')
140 | input.setAttribute('type' , 'text')
141 | input.setAttribute('value', document.getElementById(oldmac).firstChild.nodeValue)
142 | changeId(oldmac, input)
143 | obj.setAttribute('value','确定')
144 | obj.setAttribute('onclick','Submit(arr)')
145 | }
146 |
147 | //删除用户
148 | var delUser = function(obj){
149 | if(!checkFlag())return;
150 |
151 | var r = confirm("您确定要删除该设备?")
152 | if (r == true)
153 | {
154 | var arr = {}
155 | arr['method'] = 'delUser'
156 | arr['id'] = obj.name
157 | string = arrToStr(arr)
158 | ajax(Ajax_URL,check,string)
159 | }
160 | flag = 1
161 | }
162 |
163 | //删除设备
164 | var delDevice = function(obj){
165 | if(!checkFlag())return;
166 |
167 | var r = confirm("您确定要删除该设备?")
168 | if (r == true)
169 | {
170 | var arr = {}
171 | arr['id'] = obj.name
172 | arr['method'] = 'delDevice'
173 | string = arrToStr(arr)
174 | ajax(Ajax_URL,check,string)
175 | }
176 | flag = 1
177 | }
178 |
179 | var Submit = function(arr)
180 | {
181 | var send = {}
182 | if(arr['id'])
183 | {
184 | send['id'] = arr['id']
185 | }
186 | send['method'] = arr['method']
187 | for(x in arr['node'])
188 | {
189 | var node = document.getElementById(arr['node'][x])
190 | text = node.firstChild.value
191 | send[x] = text
192 | }
193 | for(x in send)
194 | {
195 | if(x == 'macaddr' && checkMac(send[x]) == false)
196 | {
197 | alert('请检查mac地址的格式')
198 | return;
199 | }
200 | }
201 | string = arrToStr(send)
202 | ajax(Ajax_URL,check,string)
203 | flag = 1
204 | }
205 |
206 | //清除流量后通过ajax方法提交
207 | var cleanFlow = function()
208 | {
209 | string = 'method=cleanFlow'
210 | ajax(Ajax_URL, check, string)
211 | flag = 1
212 | }
213 |
214 | var check = function(response){
215 | setTimeout('window.location.assign(window.location.href)',2000)
216 | }
217 |
218 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 姓名 |
9 | 总流量(M) |
10 | 已用流量(M) |
11 | 设备名 |
12 | 设备Mac地址 |
13 | 上传量(M) |
14 | 下载量(M) |
15 |
16 | $v)
25 | {
26 | $device_n = count($v['device']) + 1;
27 | $id = $k;
28 | $name = $v['name'];
29 | $total = (int)($v['total'] / 1024 / 1024);
30 | $nowflow = (int)($v['nowflow'] / 1024 / 1024);
31 | $total_flow += $v['nowflow'];
32 |
33 | $id_flow = $id . '_flow';
34 | $id_type = $id . '_newtype';
35 | $id_mac = $id . '_newmac';
36 |
37 | echo "";
38 | echo "$name | ";
39 | echo "$total | ";
40 | echo "$nowflow | ";
41 | echo "
";
42 | foreach($json['club'][$k]['device'] as $key=>$value)
43 | {
44 | $type = $value['type'];
45 | $mac = $value['mac'];
46 | $out = (int)($value['out'] / 1024 / 1024);
47 | $in = (int)($value['in'] / 1024 / 1024);
48 |
49 |
50 | $id_type = $id.'_'.$key . '_type';
51 | $id_mac = $id .'_'.$key . '_mac';
52 |
53 | $id_key = $id . '_' . $key;
54 |
55 | $total_out += (int)$value['out'];
56 | $total_in += (int)$value['in'];
57 | echo "";
58 | echo "$type | ";
59 | echo "$mac | ";
60 | echo "$out | ";
61 | echo "$in | ";
62 | echo "
";
63 |
64 | }
65 | }
66 |
67 | $id = $id + 1;
68 | $total_flow = (int)($total_flow / 1024 / 1024);
69 | $total_out = (int)($total_out / 1024 / 1024);
70 | $total_in = (int)($total_in / 1024 / 1024);
71 | echo "";
72 | echo "总计 | ";
73 | echo "30720 | ";
74 | echo "$total_flow | ";
75 | echo " | ";
76 | echo "$total_out | ";
77 | echo "$total_in | ";
78 | echo "
";
79 | ?>
80 |
81 |
82 |