5 款傻瓜式手机 APP 开发工具

Google推出的App Inventor Android App开发工具可以让你仅通过拖拉式的简单操作就可以创建自己的Android App。对于那些为了特定目的想要动手尝试开发一个简单应用的用户,除了App Inventor其实还有很多其他的选择,比如下面介绍的5款工具就可以让所有人都能轻松开发手机应用。

随着智能手机及APP应用程序的普及,越来越多的企业和个人意识到APP的营销价值,出于对技术的敬畏,很多企业下意识认为开发APP是一个有难度 的技术活,所以就算有心想开发一个企业自己的APP来对企业或者产品做宣传、交易,也担心APP的后续的技术支持、内容管理、维护等问题。

现在是打消这种疑虑的时候了。国外的营销工作者和技术开发者开发了许多能帮助企业创建简单APP应用的工具,通过这些工具,就算是一个对程序一窍不通的普通网民都可以很容易的创建一个企业的APP程序,并可以对程序进行应用更新维护,开展营销等活动。

下面给大家介绍几款傻瓜式的APP开发工具:
一、Bizness Apps


Bizness Apps为中小企业提供了一个快速制作手机App的平台。它目前支持iOS(iPhone、 iPad)及Android平台上的本机App制作。用户完全不需要具备任何编程知识,只要进行按钮勾选及拖拽,就能完成大部分设计工作。建立App时, 首先选择你的App类型。Bizness Apps为每种类型提供了相应的模板,包含了该类型大部分的常见功能,用户只需要进一步在选单中选取你的App需要的功能即可完成本机App的设计。在 App完成后,Bizness Apps会帮你把App上传到他们在iOS和Android应用商店的帐号。当然,你也可以申请帐号自己上传。选择iOS或Android之 一,Bizness Apps收费为每个平台39美元。如果选择同时支持两个平台,总共仅需59美元。这个价格对于中小企业来说实在很有吸引力,只需要一比颇小的投入,就能利 用App进行品牌营销。

同时,Bizness Apps公司还发布了其HTML5的手机App制作平台,中小企业们只要额外支付每月10美元的费用, 就可以同时拥有本机应用和HTML5的Web应用。HTML5的手机App最大的好处无疑在于其跨平台特性,客户只要制作基于HTML5的App就可以实 现对所有智能机平台的支持。

作为HTML5平台发布的一部分,Bizness Apps还建立了一个QR码模块,帮助中小企业进行手机App推广。消费者只要用手机扫一遍QR码,就能快速定位到对应平台的App。

Bizness Apps简明的操作、强大的功能以及美观的UI,吸引了众多中小企业使用他们的服务。自去年10月正 式上线以来,其增长势头异常迅猛,已经完成了超过1000个App,覆盖10多种语言,20多个国家。

二、DevmyApp


一款傻瓜式的iOS应用程序开发软件。有了该应用,您就可以创建、设计和开发自己的iOS应用程序,同时还可避免为一些经常出现的功能模块重复编写代码。
DevmyApp的主要特色功能有:

 

  • 视图和过渡:创建视图并为其增加动画过渡效果。
  • 共享 应用:启动外部原生应用,如Safari、电话或短信等。
  • 动画:创建基本的动画。
  • 网页视图:创建网页视图用自定义的控制方式导航互联网。
  • 地图视图:创建可在混合地图和卫星地图之间切换的地图并可提示用户位置。
  • 滚动文字:创建在屏幕上滚动的标签。
  • 摇晃 API:创建摇晃iDevice时执行的操作。
  • 应用内程序:启动消息或邮件等原生应用并在应用内使用。
  • 提醒视图:创建自定义提醒视图。
  • 旋转模式:当您转动iDevice时使应用支持横屏模式。
  • 振动:使特定操作触发振动。

每项特色功能都带有说明并可预览应用内集成的实际例子的效果,而且还可预览代码和通过邮件发送代码。代码中包含注释和解释,您可对其进行修改满足您应用程序的需要。

对于想要通过强大的功能增强创意的iOS开发人员和iOS平台开发新手,该应用都是必备应用。

注意:

  • 要开发iOS程序,您需要有一台Mac系统的电脑。
  • 若要理解和运用该应用中包含的代码,您需有一定编程知识(特别是Objective-C语言)。

三、appsgeyser


使用AppsGeyser就可以让任何人都可以做应用程序的开发。 当然,这个程序并不能让你创建下一个愤怒的小鸟或者Foursquare。不过你仅仅想基于Web内容建立一个非常简单的应用程序的 话,AppsGeyser将会是你最佳的选择。AppsGeyser其实非常容易。它仅仅有三个选项:
首先,你可以任意输入一个移动网站网址,即可生成一个应用;第二,输入任何网页小工具的HTML代码,便可直接转化为Android应用;第三,通过工具抓取网页上的版块生成应用。

一旦你的工作完成后,你可以将其上传到Android Market上(但你事先要有一个出版商帐号)或者供你自己使用这个程序上个月才可以使用,但其联合创始人Vasily Salomatov称用户已经用AppsGeyser创建了1000个应用程序。

四、APPMakr


这个是之前我在《APP不是移动互联网的全部》一文中介绍过的APP开发工具,但是类似的工具还很少。

它的主要业务是为用户提供一个软件开发平台,让不会编程的用户也可以通过一个功能齐全的DIY工具包来开发手机应用程序。目前,AppMakr平台上的大部分应用主要是针对iOS系统,但针对Android及WP7的应用现在也正不断增长中。

基于浏览器的AppMakr可以整合用户已有的网页内容和社交网站更新,也帮助出版商、博客用户、小企业家和其他手机程序爱好者整合短信提示、相册 和 定位功能。它甚至还提供手机广告网络整合工具来增加开发者的赚钱机会。AppMakr为用户设计了算法来预测程序获得批准的可能性,标记出程序的潜在问题 并提出必要的程序修改建议。一旦程序通过审批并开始提供下载,用户就可以通过AppMakr操作版面查看进程,发布给消费者新信息并进行程序升级等。截至 2011年5月,已经有约3700个iPhone程序由AppMakr平台开发,这超过了苹果店全部iPhone应用程序库存的1%。

在具体使用过程中,用户首先需要注册一个AppMakr账号。注册完就可以立刻开始制作你的应用,然后选择应用模板如Android、iPhone等。

AppMakr的整个应用制作流程分七步。

  • 第一步是Art这个版面,这里是设置你应用的名称,图标和启动画面。用户可以通过AppMakr的搜索功能到网上找一张适合的图,或者选择自己上传。
  • 第二步来到Tab版面,这是比较重要的一个地方,设置你所制作的应用中内容,你应用的内容可以来自网络相册,然后你的应用就是展示这些图片。也可以来自某RSS的内容,你的应用就是用来展示它。
  • 第三步来到自定义版面,这里是设置你应用中内容的文字颜色和把内容发到其他地方,如Facebook,但你想发布到这些网站的前提是有这些网站的开发者ID。
  • 第四步来到通知推送版面,开发者可在这里设置应用对手机推送通知时的显示图样。
  • 第五步来到应用信息版面,开发者可以在这里是对自己的应用做一些背景描述。
  • 第六步是商业化版面,在这里开发者可以为自己的应用添加广告,以在日后获取广告费,但需要去对应的广告网站注册一个相关ID。
  • 最后一步是发布版面,在发布前,开发者要提交一个自己的证书进行认证,认证结束以后就可以真正去发布自己制作的应用。

五、Mobile Roadie


Mobile Roadie提供一个应用开发平台,整合YouTube, Brightcove, Flickr, Twitpic, Ustream, Topspin, Google资讯,RSS, Twitter和Facebook。用户可使用该应用平台开发iOS应用和Android应用,并可以使用其提供的内容管理系统更新资讯,也可自行修改应 用细节。Mobile Roadie还提供了数据分析工具。

Mobile Roadie至今已开发出超过1500款应用程序,在全球拥有一千多万用户,支持16种语言,在美国、法国、西班牙、澳大利亚、加拿大、意大利、韩国和日 本市场均有出色表现。Q魔宝是Mobile Roadie在中国的本地化产品,由Mobile Roadie提供技术支持,飞客(中国)有限公司负责经销。用户可通过互联网登录Q魔宝平台,在网页拖拽界面上,轻松创建专属的iPhone及 Android应用程序,整个过程只需短短数小时

Mobile Roadie现已进入英国,法国,西班牙,澳大利亚,意大利,德国,巴西,土耳其和日本市场。

当然,APP开发工具不仅仅这些,例如:

  • 专为艺术家打造的SwebApps

功能:SwebApps提供了一种在线服务,让你即便不知道如何编写代码也可以开发iPhone软件。 专为小公司打造,提供多种可供定制的模板,你还可以使用他们的图片库。

  • 开发电子书应用利器 eBook App

功能: T用于通过电子书创建软件几乎支持所有格式的文件:PDF, Doc, Zip, CHM, HTML, TXT, FB2, PDB, PRC, Mobi, PDB, MHT, RTF此外用户还可以选择字体和大小,添加图片和注释,锁定横屏或竖屏等

  • 游戏创意的实现者 GameSalad

功能: 这个下载工具可以让用户无需了解编程或脚本知识就可以开发游戏开发的软件可以发布到网页或iPhone上
……
期待有一天,APP开发好比纸上画图一样简单!

 

[转载]PHP抓取网页内容汇总

①、使用php获取网页内容
http://hi.baidu.com/quqiufeng/blog/item/7e86fb3f40b598c67d1e7150.html
header(“Content-type: text/html; charset=utf-8”);
1、
$xhr = new COM(“MSXML2.XMLHTTP”);
$xhr->open(“GET”,”http://localhost/xxx.php?id=2″,false);
$xhr->send();
echo $xhr->responseText

2、file_get_contents实现
<?php
$url=”http://www.blogjava.net/pts”;
echo file_get_contents( $url );
?>

3、fopen()实现
<?
if ($stream = fopen(‘http://www.sohu.com’, ‘r’)) {
// print all the page starting at the offset 10
echo stream_get_contents($stream, -1, 10);
fclose($stream);
}

if ($stream = fopen(‘http://www.sohu.net’, ‘r’)) {
// print the first 5 bytes
echo stream_get_contents($stream, 5);
fclose($stream);
}
?>

②、使用php获取网页内容
http://www.blogjava.net/pts/archive/2007/08/26/99188.html
简单的做法:
<?php
$url=”http://www.blogjava.net/pts”;
echo file_get_contents( $url );
?>
或者:
<?
if ($stream = fopen(‘http://www.sohu.com’, ‘r’)) {
// print all the page starting at the offset 10
echo stream_get_contents($stream, -1, 10);
fclose($stream);
}

if ($stream = fopen(‘http://www.sohu.net’, ‘r’)) {
// print the first 5 bytes
echo stream_get_contents($stream, 5);
fclose($stream);
}
?>

③、PHP获取网站内容,保存为TXT文件源码
http://blog.chinaunix.net/u1/44325/showart_348444.html
<?
$my_book_url=’http://book.yunxiaoge.com/files/article/html/4/4550/index.html’;
ereg(“http://book.yunxiaoge.com/files/article/html/[0-9]+/[0-9]+/”,$my_book_url,$myBook);
$my_book_txt=$myBook[0];
$file_handle = fopen($my_book_url, “r”);//读取文件
unlink(“test.txt”);
while (!feof($file_handle)) { //循环到文件结束
$line = fgets($file_handle); //读取一行文件
$line1=ereg(“href=\”[0-9]+.html”,$line,$reg); //分析文件内部书的文章页面
$handle = fopen(“test.txt”, ‘a’);
if ($line1) {
$my_book_txt_url=$reg[0]; //另外赋值,给抓取分析做准备
$my_book_txt_url=str_replace(“href=\””,””,$my_book_txt_url);
$my_book_txt_over_url=”$my_book_txt$my_book_txt_url”; //转换为抓取地址
echo “$my_book_txt_over_url</p>”; //显示工作状态
$file_handle_txt = fopen($my_book_txt_over_url, “r”); //读取转换后的抓取地址
while (!feof($file_handle_txt)) {
$line_txt = fgets($file_handle_txt);
$line1=ereg(“^&nbsp.+”,$line_txt,$reg); //根据抓取内容标示抓取
$my_over_txt=$reg[0];
$my_over_txt=str_replace(“&nbsp;&nbsp;&nbsp;&nbsp;”,”    “,$my_over_txt); //过滤字符
$my_over_txt=str_replace(“<br />”,””,$my_over_txt);
$my_over_txt=str_replace(“<script. language=\”javascript\”>”,””,$my_over_txt);
$my_over_txt=str_replace(“&quot;”,””,$my_over_txt);
if ($line1) {
$handle1=fwrite($handle,”$my_over_txt\n”); //写入文件
}
}
}
}
fclose($file_handle_txt);
fclose($handle);
fclose($file_handle); //关闭文件
echo “完成</p>”;
?>

下面是比较嚣张的方法。
这里使用一个名叫Snoopy的类。
先是在这里看到的:
PHP中获取网页内容的Snoopy包
http://blog.declab.com/read.php/27.htm
然后是Snoopy的官网:
http://sourceforge.net/projects/snoopy/
这里有一些简单的说明:
代码收藏-Snoopy类及简单的使用方法
http://blog.passport86.com/?p=161
下载:http://sourceforge.net/projects/snoopy/

今天才发现这个好东西,赶紧去下载了来看看,是用的parse_url
还是比较习惯curl

snoopy是一个php类,用来模仿web浏览器的功能,它能完成获取网页内容和发送表单的任务。
下面是它的一些特征:
1、方便抓取网页的内容
2、方便抓取网页的文字(去掉HTML代码)
3、方便抓取网页的链接
4、支持代理主机
5、支持基本的用户/密码认证模式
6、支持自定义用户agent,referer,cookies和header内容
7、支持浏览器转向,并能控制转向深度
8、能把网页中的链接扩展成高质量的url(默认)
9、方便提交数据并且获取返回值
10、支持跟踪HTML框架(v0.92增加)
11、支持再转向的时候传递cookies

具体使用请看下载文件中的说明。
<?php
include“Snoopy.class.php“;
$snoopy=newSnoopy;
$snoopy->fetchform(“http://www.phpx.com/happy/logging.php?action=login“);
print$snoopy->results;
?>
<?php
include“Snoopy.class.php“;
$snoopy=newSnoopy;
$submit_url=“http://www.phpx.com/happy/logging.php?action=login“;$submit_vars[“loginmode”]=“normal“;
$submit_vars[“styleid”]=“1“;
$submit_vars[“cookietime”]=“315360000“;
$submit_vars[“loginfield”]=“username“;
$submit_vars[“username”]=“********“;//你的用户名
$submit_vars[“password”]=“*******“;//你的密码
$submit_vars[“questionid”]=“0“;
$submit_vars[“answer”]=“”;
$submit_vars[“loginsubmit”]=“提 &nbsp; 交“;
$snoopy->submit($submit_url,$submit_vars);
print$snoopy->results;?>

下面是Snoopy的Readme
NAME:

Snoopy – the PHP net client v1.2.4

SYNOPSIS:

include “Snoopy.class.php”;
$snoopy = new Snoopy;

$snoopy->fetchtext(“http://www.php.net/”);
print $snoopy->results;

$snoopy->fetchlinks(“http://www.phpbuilder.com/”);
print $snoopy->results;

$submit_url = “http://lnk.ispi.net/texis/scripts/msearch/netsearch.html”;

$submit_vars[“q”] = “amiga”;
$submit_vars[“submit”] = “Search!”;
$submit_vars[“searchhost”] = “Altavista”;

$snoopy->submit($submit_url,$submit_vars);
print $snoopy->results;

$snoopy->maxframes=5;
$snoopy->fetch(“http://www.ispi.net/”);
echo “<PRE>\n”;
echo htmlentities($snoopy->results[0]);
echo htmlentities($snoopy->results[1]);
echo htmlentities($snoopy->results[2]);
echo “</PRE>\n”;

$snoopy->fetchform(“http://www.altavista.com”);
print $snoopy->results;

DESCRIPTION:

What is Snoopy?

Snoopy is a PHP class that simulates a web browser. It automates the
task of retrieving web page content and posting forms, for example.

Some of Snoopy’s features:

* easily fetch the contents of a web page
* easily fetch the text from a web page (strip html tags)
* easily fetch the the links from a web page
* supports proxy hosts
* supports basic user/pass authentication
* supports setting user_agent, referer, cookies and header content
* supports browser redirects, and controlled depth of redirects
* expands fetched links to fully qualified URLs (default)
* easily submit form. data and retrieve the results
* supports following html frames (added v0.92)
* supports passing cookies on redirects (added v0.92)

REQUIREMENTS:

Snoopy requires PHP with PCRE (Perl Compatible Regular Expressions),
which should be PHP 3.0.9 and up. For read timeout support, it requires
PHP 4 Beta 4 or later. Snoopy was developed and tested with PHP 3.0.12.

CLASS METHODS:

fetch($URI)
———–

This is the method used for fetching the contents of a web page.
$URI is the fully qualified URL of the page to fetch.
The results of the fetch are stored in $this->results.
If you are fetching frames, then $this->results
contains each frame. fetched in an array.

fetchtext($URI)
—————

This behaves exactly like fetch() except that it only returns
the text from the page, stripping out html tags and other
irrelevant data.

fetchform($URI)
—————

This behaves exactly like fetch() except that it only returns
the form. elements from the page, stripping out html tags and other
irrelevant data.

fetchlinks($URI)
—————-

This behaves exactly like fetch() except that it only returns
the links from the page. By default, relative links are
converted to their fully qualified URL form.

submit($URI,$formvars)
———————-

This submits a form. to the specified $URI. $formvars is an
array of the form. variables to pass.

submittext($URI,$formvars)
————————–

This behaves exactly like submit() except that it only returns
the text from the page, stripping out html tags and other
irrelevant data.

submitlinks($URI)
—————-

This behaves exactly like submit() except that it only returns
the links from the page. By default, relative links are
converted to their fully qualified URL form.
CLASS VARIABLES:    (default value in parenthesis)

$host            the host to connect to
$port            the port to connect to
$proxy_host        the proxy host to use, if any
$proxy_port        the proxy port to use, if any
$agent            the user agent to masqerade as (Snoopy v0.1)
$referer        referer information to pass, if any
$cookies        cookies to pass if any
$rawheaders        other header info to pass, if any
$maxredirs        maximum redirects to allow. 0=none allowed. (5)
$offsiteok        whether or not to allow redirects off-site. (true)
$expandlinks    whether or not to expand links to fully qualified URLs (true)
$user            authentication username, if any
$pass            authentication password, if any
$accept            http accept types (image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*)
$error            where errors are sent, if any
$response_code    responde code returned from server
$headers        headers returned from server
$maxlength        max return data length
$read_timeout    timeout on read operations (requires PHP 4 Beta 4+)
set to 0 to disallow timeouts
$timed_out        true if a read operation timed out (requires PHP 4 Beta 4+)
$maxframes        number of frames we will follow
$status            http status of fetch
$temp_dir        temp directory that the webserver can write to. (/tmp)
$curl_path        system path to cURL binary, set to false if none
EXAMPLES:

Example:     fetch a web page and display the return headers and
the contents of the page (html-escaped):

include “Snoopy.class.php”;
$snoopy = new Snoopy;

$snoopy->user = “joe”;
$snoopy->pass = “bloe”;

if($snoopy->fetch(“http://www.slashdot.org/”))
{
echo “response code: “.$snoopy->response_code.”<br>\n”;
while(list($key,$val) = each($snoopy->headers))
echo $key.”: “.$val.”<br>\n”;
echo “<p>\n”;

echo “<PRE>”.htmlspecialchars($snoopy->results).”</PRE>\n”;
}
else
echo “error fetching document: “.$snoopy->error.”\n”;

 

Example:    submit a form. and print out the result headers
and html-escaped page:

include “Snoopy.class.php”;
$snoopy = new Snoopy;

$submit_url = “http://lnk.ispi.net/texis/scripts/msearch/netsearch.html”;

$submit_vars[“q”] = “amiga”;
$submit_vars[“submit”] = “Search!”;
$submit_vars[“searchhost”] = “Altavista”;
if($snoopy->submit($submit_url,$submit_vars))
{
while(list($key,$val) = each($snoopy->headers))
echo $key.”: “.$val.”<br>\n”;
echo “<p>\n”;

echo “<PRE>”.htmlspecialchars($snoopy->results).”</PRE>\n”;
}
else
echo “error fetching document: “.$snoopy->error.”\n”;

 

Example:    showing functionality of all the variables:
include “Snoopy.class.php”;
$snoopy = new Snoopy;

$snoopy->proxy_host = “my.proxy.host”;
$snoopy->proxy_port = “8080”;

$snoopy->agent = “(compatible; MSIE 4.01; MSN 2.5; AOL 4.0; Windows 98)”;
$snoopy->referer = “http://www.microsnot.com/”;

$snoopy->cookies[“SessionID”] = 238472834723489l;
$snoopy->cookies[“favoriteColor”] = “RED”;

$snoopy->rawheaders[“Pragma”] = “no-cache”;

$snoopy->maxredirs = 2;
$snoopy->offsiteok = false;
$snoopy->expandlinks = false;

$snoopy->user = “joe”;
$snoopy->pass = “bloe”;

if($snoopy->fetchtext(“http://www.phpbuilder.com”))
{
while(list($key,$val) = each($snoopy->headers))
echo $key.”: “.$val.”<br>\n”;
echo “<p>\n”;

echo “<PRE>”.htmlspecialchars($snoopy->results).”</PRE>\n”;
}
else
echo “error fetching document: “.$snoopy->error.”\n”;
Example:     fetched framed content and display the results

include “Snoopy.class.php”;
$snoopy = new Snoopy;

$snoopy->maxframes = 5;

if($snoopy->fetch(“http://www.ispi.net/”))
{
echo “<PRE>”.htmlspecialchars($snoopy->results[0]).”</PRE>\n”;
echo “<PRE>”.htmlspecialchars($snoopy->results[1]).”</PRE>\n”;
echo “<PRE>”.htmlspecialchars($snoopy->results[2]).”</PRE>\n”;
}
else
echo “error fetching document: “.$snoopy->error.”\n”;

 

Snoopy-2.0.0.tar.gz

[转载]提示“出现错误1327!无效驱动器:G:\”的解决方案

2008-09-04 19:35:03

提示“出现错误1327!无效驱动器:G:\”
单击开始菜单-运行,输入
subst G: %TEMP%
然后继续你的操作,就行了。这时你会发现机器里又多了系统盘符G,应该是虚拟的安装环境。
如果你要删除这个虚拟出来的G盘,只要执行“subst G:/D”命令就行,但此命令要重启后才能发现我的电脑里的虚拟盘没有了。
关于这条命令的详细介绍
subst.exe是一个不太常用的DOS命令,它的位置隐藏在\Windows\Command\下(针对Windows 9X/Me系统),如果是Windows 2000/XP,则应该隐藏在\Windows\System32\下,前者的大小为17.6KB,后者的大小更小一些,才9.0KB而已。
subst.exe的完整名称是“给目录赋驱动器符命令”,它的功能是以磁盘驱动器号代替路径名称,以使驱动器号与指定的子目录路径关联,其命令格式很简单:
  subst.exe [Driver1: [Driver2:] Path]
  其中的“Driver1”是指定指派路径的虚拟驱动器盘符,“Driver2 Path”则是指定物理驱动器和要指派给虚拟驱动器的路径。
  2.利用subst.exe虚拟软驱
例如,在安装瑞星杀毒软件前,你可以先通过其他方式(例如局域网、邮件、共享文件)将A盘的所有文件复制到本机的一个文件夹中,例如D:\temp 下。然后在命令提示符窗口下键入如下命令“subst A: D:\temp”,如图1所示,朋友们可以看一看这里用“dir A:”命令后的文件列表,就知道一张软盘中是绝不可能放入如此之多的东东的。这样,我们就可以按照这种方法将D:\temp文件夹虚拟成A盘,瑞星杀毒软 件的安装就可以顺利完成了。
  当我们虚拟软驱后,你会发觉软驱的图标已经变成了图2所示的硬盘图标,当然双击打开后就是D:\Temp文件夹中的内容。
  3.删除虚拟软驱
如果你要删除这个虚拟出来的A盘,只要执行“subst A:/D”命令就行了,切记工作结束后一定要及时删除这个虚拟出来的A盘,否则无法正常使用原来的物理A盘哟。

有些软件只能在软盘上运行,这是软件开发者的特别设计,主要目的是为了防止非法拷贝。不过,我们可以先通过HD-COPY工具将软盘做成一 个扩展名为img的镜像文件存放在硬盘上的某个文件夹中,然后利用IMGDRIVE、UNDISK等工具软件将该镜像文件展开,这样就可以在硬盘上创建一个虚拟软盘,自然也就可以正常运行了,不过如果是加密的软件,则无法通过这种方法正常运行。

【转载】什么是WiFi无缝漫游(即无线AP自动切换)?

很多客户经常问我:小钟,你们的WiFi会出现很多的WiFi名称吗?例如XX酒店WiFi 1、XX酒店WiFi 2,这样的情况会有吗?很多工程商客户之前都做过WiFi覆盖的,会有这样的困惑——WiFi不能自动切换,例如在酒店的大厅连接了WiFi了,不过走到客房里面之后,大厅的WiFi没有信号了,要自己手动去连接上另外一个WiFi,而且又要手动去输入一次密码,又要等,这样是不是比较麻烦,经常给客户投诉?
小钟在这里很诚实的告诉大家:我们的WiFi名称只会出现一个,而且无论你走到哪里,只要是我们WiFi设备发出来的信号,都不会断,全程都会自动连接WiFi, 比如一家酒店用的是我们的WiFi产品去做WiFi覆盖的,你在酒店的大厅输入了WiFi密码,连接WiFi后,无论你走到哪里,只要有我们WiFi设备发出来的信号,它们都可以自己连上WiFi,不自己手动去连接和再输入一次WiFi密码,我们叫这个功能是——WiFi 无缝漫游。

(示意图)
无线AP配置规划(无线设备在多个AP间自动无线漫游)
无线漫游中无线AP的配置与普通无线AP的配置基本相同,只是应当注意以下几个方面的问题:
所有无线AP必须使用同一SSID。
所有无线AP必须使用同一网段的IP地址,并且处于同一VLAN中。
信号相互覆盖的无线AP不能使用相同的频道。
由于多个AP信号覆盖区域相互交叉重叠,因此,各个AP覆盖区域所占频道之间必须遵守一定的规范,邻近的相同频道之间不能相互覆盖,也就是说,相互覆盖区域的无线AP不能采用同一频道,否则,会造成AP在信号传输时的相互干扰,从而降低AP的工作效率。在可用的11个频道中,仅有3个频道是完全不覆盖的,他们分别是频道1、频道6和频道11,利用这些频道作为多蜂窝覆盖是最合适的。另外,用于实现无线漫游网络的无线AP必须使用同一网络名称(SSID),使用同一网段的IP地址,否则,无线客户端将无法实现漫游功能。
无线漫游网络中,客户端的配置与接入点网络中的配置完全相同。用户在移动过程中,根本感觉不到无线AP间进行切换。

在搭建无线漫游网络时,需要注意以下几点:
1:AP信号覆盖区域应当相互交叉重叠,否则,会导致无线网络盲区。也就是说,无线AP之间的距离,应当小于无线AP的有限传输距离。 相互覆盖的无线AP必须采用不同的、甚至是不相邻频道,否则,将导致严重干扰,降低AP通信效率。信道就是之频段,IEEE 802.11b/g是工作在2400~2 483MHz,美国标准信道(channel)可以划分11个,欧洲标准可以划分13个,日本标准可以划分14个,每个channel之间相差11MHz。如channel1为2 412MHz,channel2为2 423MHz,依此类推。事实上,只有1、6、11信道之间是完全没有干扰的。
2:无线AP必须设置为相同的SSID。不同的SSID意味着不同的无线网络,而无法实现无线漫游。需要注意的是,SSID区分大小写。
必须采用相同的WEP或WPA加密。所有无线AP和客户端必须采用相同的WEP或WPA加密,否则,将无法建立彼此之间的连接。WEP和WPA也是区分大小写的。
3:无线AP与无线客户端必须处于同一VLAN、同一IP地址段。

http://tieba.baidu.com/p/3274443902

[转载]ASP时间函数

本文提供vbscript基本函数介绍

基本函数

date() –创建日期变量,显示格式:2004-2-28
time() –创建时间变量,显示格式:22:24:59
now() –创建日期和时间变量, 显示格式: 2005-5-2 22:37:30

单独获取年、月、日、时、分、秒:

先创建日期变量d=date()

获取年份:year(d)
获取月份:month(d)
获取日子:day(d)
获取星期几:weekday(d)

先创建t=time()

获取小时:hour(t)
获取分钟:minute(t)
获取秒数:second(t)

 

日期推算函数(根据给定的日期、再增加或者减去一个时间量,得到另一个日期)

DateAdd(interval, number, date)

参数说明:

interval-运算的基准间隔

number-加上多少,为负数就是减去时间量

date-基准日期

下面是interval的可选值,注意使用时加上引号(“):

设置 描述
yyyy
q 季度
m
y 一年的日数
d
w 一周的日数
ww
h 小时
n 分钟
s

日期相加举例:

1、计算明天:

tomorrow=DateAdd(“d”,1,date())

2、2012年12月1日的前一天:

preday=DateAdd(“d”,-1,”2012-12-1″)

日期相减函数(计算两个日期之间的间隔时间量)

DateDiff(interval, date1, date2[, firstdayofweek][, firstweekofyear]])

计算两个日期之间相差的间隔。

例如,来计算两个日期之间相隔几日;或计算从今天起到年底还有多少个星期。如果date1比date2 晚,则返回负数。 返回值的单位由interval决定。

参数说明:

interval-同DateAdd()函数

Date1,date2 -进行运算的两个日期

可选参数:

firstdayofweek- 指定一个星期的第一天的常数。如果未予指定,则以星期日为第一天。当计算两个日期相差几周时(时间间隔符号 “w” 或 “ww”),该参数会影响结果。具体请搜索。

firstweekofyear-指定一年的第一周怎么确定,如果未予指定,则以包含 1 月 1 日的星期为第一周。具体请搜索。

 

通过指定日期创建日期和时间变量

DateSerial(year, month, day)

该函数能自动调整输入数值:比如输入day=35,则自动计算到下个月。再比如:DateSerial(1990 – 10, 8 – 2, 1 – 1) 则计算1990 年8月1日的十年零两个月又一天  之前的日期,也就是1980年5月31日。

DateValue(date)-通过各种日期格式串创建日期变量。例如输入:12/30/1991 、 December 30, 1991 、 Dec 30, 1991。

TimeSerial(hour, minute, second) -将数值转化为时间变量。原理同DateSerial。

TimeValue(time)-将各种时间格式串转化为时间变量。原理同DateValue。
获取日期的部份值

DatePart(interval, date[,firstdayofweek[, firstweekofyear]]) -。例如,可以使用DatePart 计算某个日期是星期几或目前为几点钟。

举例;
d = #2/10/96 16:45:30#
DatePart(“yyyy”,d)) ‘1996
DatePart(“m”,d) ‘2
DatePart(“d”,d) ’10
DatePart(“h”,d) ’16
DatePart(“n”,d) ’45
DatePart(“s”,d) ’30
DatePart(“q”,d) ‘1—2月是第1季
DatePart(“y”,d) ’41—2月10日是1996年的第41日。
DatePart(“ww”,d) ‘6—2月10日是1996年的第6周。
DatePart(“w”,d) ‘7—2月10日在在1996年是第6周的第7日(星期六)。其他:

Timer()-午夜开始到现在经过的秒数,带两位小数点数值。

[转载][SQL SERVER] 跨服务器查询

[SQL SERVER] 跨服务器查询

方法一:
用OPENDATASOURCE
下面是个跨SQLServer查询的示例
Select TableA.*,TableB.* From OPENDATASOURCE(
‘SQLOLEDB’,
‘Data Source=ServerA;User ID=UserID;Password=Password’
).databaseAName.dbo.TableA
Left Join
OPENDATASOURCE(
‘SQLOLEDB’,
‘Data Source=ServerB;User ID=UserID;Password=Password’
).databaseBName.dbo.TableB On TableA.key=TableB.key

下面是个查询的示例,它通过用于 Jet 的 OLE DB 提供程序查询 Excel 电子表格。
SELECT *
FROM OpenDataSource( ‘Microsoft.Jet.OLEDB.4.0’,
‘Data Source=”c:\Finance\account.xls”;User ID=Admin;Password=;Extended properties=Excel 5.0’)…xactions

方法二(也可以在企业管理器里添加 linkServer):
sp_addlinkedserver
创建一个链接的服务器,使其允许对分布式的、针对 OLE DB 数据源的异类查询进行访问。在使用 sp_addlinkedserver 创建链接的服务器之后,此服务器就可以执行分布式查询。如果链接服务器定义为 Microsoft? SQL Server?,则可执行远程存储过程。

语法
sp_addlinkedserver [ @server = ] ‘server’
[ , [ @srvproduct = ] ‘product_name’ ]
[ , [ @provider = ] ‘provider_name’ ]
[ , [ @datasrc = ] ‘data_source’ ]
[ , [ @location = ] ‘location’ ]
[ , [ @provstr = ] ‘provider_string’ ]
[ , [ @catalog = ] ‘catalog’ ]

权限
执行许可权限默认授予 sysadmin 和 setupadmin 固定服务器角色的成员。

简单示例:
//创建linkServer
exec sp_addlinkedserver ‘srv_lnk’,”,’SQLOLEDB’,’服务器名’
//登陆linkServer
exec sp_addlinkedsrvlogin ‘srv_lnk’,’false’,null,’用户名’,’密码’
//查询linkServer的数据库DataBaseA的表TableA
Select * From srv_lnk.DataBaseA.dbo.TableA
//List the tables in the linked server
EXEC sp_tables_ex txtsrv

 

示例
A. 使用用于 SQL Server 的 Microsoft OLE DB 提供程序
使用用于 SQL Server 的 OLE DB 创建链接服务器
下面的示例创建一台名为 SEATTLESales 的链接服务器,该服务器使用用于 SQL Server 的 Microsoft OLE DB 提供程序。

USE master
GO
EXEC sp_addlinkedserver
‘SEATTLESales’,
N’SQL Server’
GO

在 SQL Server 的实例上创建链接服务器
此示例在 SQL Server 的实例上创建一台名为 S1_instance1 的链接服务器,该服务器使用 SQL Server 的 Microsoft OLE DB 提供程序。

EXEC    sp_addlinkedserver    @server=’S1_instance1′, @srvproduct=”,
@provider=’SQLOLEDB’, @datasrc=’S1\instance1′

B. 使用用于 Jet 的 Microsoft OLE DB 提供程序
此示例创建一台名为 SEATTLE Mktg 的链接服务器。

 

说明  本示例假设已经安装 Microsoft Access 和示例 Northwind 数据库,且 Northwind 数据库驻留在 C:\Msoffice\Access\Samples。
USE master
GO
— To use named parameters:
EXEC sp_addlinkedserver
@server = ‘SEATTLE Mktg’,
@provider = ‘Microsoft.Jet.OLEDB.4.0’,
@srvproduct = ‘OLE DB Provider for Jet’,
@datasrc = ‘C:\MSOffice\Access\Samples\Northwind.mdb’
GO
— OR to use no named parameters:
USE master
GO
EXEC sp_addlinkedserver
‘SEATTLE Mktg’,
‘OLE DB Provider for Jet’,
‘Microsoft.Jet.OLEDB.4.0’,
‘C:\MSOffice\Access\Samples\Northwind.mdb’
GO

C. 使用用于 Oracle 的 Microsoft OLE DB 提供程序
此示例创建一台名为 LONDON Mktg 的链接服务器,该服务器使用用于 Oracle 的 Microsoft OLE DB 提供程序,并且假设此 Oracle 数据库的 SQL*Net 别名为 MyServer。

USE master
GO
— To use named parameters:
EXEC sp_addlinkedserver
@server = ‘LONDON Mktg’,
@srvproduct = ‘Oracle’,
@provider = ‘MSDAORA’,
@datasrc = ‘MyServer’
GO
— OR to use no named parameters:
USE master
GO
EXEC sp_addlinkedserver
‘LONDON Mktg’,
‘Oracle’,
‘MSDAORA’,
‘MyServer’
GO

D. 将 data_source 参数与用于 ODBC 的 Microsoft OLE DB 提供程序一起使用
此示例创建一台名为 SEATTLE Payroll 的链接服务器,该服务器使用用于 ODBC 的 Microsoft OLE DB 提供程序和 data_source 参数。

 

说明  在执行 sp_addlinkedserver 之前,必须在服务器上将指定的 ODBC 数据源名称定义为系统 DSN。
USE master
GO
— To use named parameters:
EXEC sp_addlinkedserver
@server = ‘SEATTLE Payroll’,
@provider = ‘MSDASQL’,
@datasrc = ‘LocalServer’
GO
— OR to use no named parameters:
USE master
GO
EXEC sp_addlinkedserver
‘SEATTLE Payroll’,
”,
‘MSDASQL’,
‘LocalServer’
GO

E. 将 provider_string 参数与用于 ODBC 的 Microsoft OLE DB 提供程序一起使用
此示例创建一台名为 LONDON Payroll 的链接服务器,该服务器使用用于 ODBC 的 Microsoft OLE DB 提供程序和 provider_string 参数。

 

说明  有关 ODBC 连接字符串的更多信息,请参见 SQLDriverConnect 和如何分配句柄并与 SQL Server (ODBC) 连接。
USE master
GO
— To use named parameters:
EXEC sp_addlinkedserver
@server = ‘LONDON Payroll’,
@provider = ‘MSDASQL’,
@provstr = ‘DRIVER={SQL Server};SERVER=MyServer;UID=sa;PWD=;’
GO
— OR to use no named parameters:
USE master
GO
EXEC sp_addlinkedserver
‘LONDON Payroll’,
”,
‘MSDASQL’,
NULL,
NULL,
‘DRIVER={SQL Server};SERVER=MyServer;UID=sa;PWD=;’
GO

F. 在 Excel 电子表格上使用用于 Jet 的 Microsoft OLE DB 提供程序
若要创建使用用于 Jet 的 Microsoft OLE DB 提供程序以访问 Excel 电子表格的链接服务器定义,请首先在 Excel 中创建一个命名的范围以指定要在 Excel 工作表中选择的行和列。然后,可将此范围的名称引用为分布式查询中的表名称。

EXEC sp_addlinkedserver ‘ExcelSource’,
‘Jet 4.0’,
‘Microsoft.Jet.OLEDB.4.0’,
‘c:\MyData\DistExcl.xls’,
NULL,
‘Excel 5.0’
GO

为了访问 Excel 电子表格中的数据,请将某个范围内的单元与某个名称相关联。通过将范围的名称用作表名称,可以访问指定的已命名范围。下列查询利用前面设置的链接服务器,可访问称为 SalesData 的命名范围。

SELECT *
FROM EXCEL…SalesData
GO

G. 使用用于检索服务的 Microsoft OLE DB 提供程序
此示例创建一台链接服务器,并且使用 OPENQUERY 从为检索服务启用的链接服务器和文件系统中检索信息。

EXEC sp_addlinkedserver FileSystem,
‘Index Server’,
‘MSIDXS’,
‘Web’
GO
USE pubs
GO
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = ‘yEmployees’)
DROP TABLE yEmployees
GO
CREATE TABLE yEmployees
(
id       int         NOT NULL,
lname    varchar(30) NOT NULL,
fname    varchar(30) NOT NULL,
salary   money,
hiredate datetime
)
GO
INSERT yEmployees VALUES
(
10,
‘Fuller’,
‘Andrew’,
$60000,
‘9/12/98’
)
GO
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_NAME = ‘DistribFiles’)
DROP VIEW DistribFiles
GO
CREATE VIEW DistribFiles
AS
SELECT *
FROM OPENQUERY(FileSystem,
‘SELECT Directory,
FileName,
DocAuthor,
Size,
Create,
Write
FROM SCOPE(” “c:\My Documents” ”)
WHERE CONTAINS(”Distributed”) > 0
AND FileName LIKE ”%.doc%” ‘)
WHERE DATEPART(yy, Write) = 1998
GO
SELECT *
FROM DistribFiles
GO
SELECT Directory,
FileName,
DocAuthor,
hiredate
FROM DistribFiles D, yEmployees E
WHERE D.DocAuthor = E.FName + ‘ ‘ + E.LName
GO

H. 使用用于 Jet 的 Microsoft OLE DB 提供程序访问文本文件
此示例创建一台直接访问文本文件的链接服务器,而没有将这些文件链接为 Access .mdb 文件中的表。提供程序是 Microsoft.Jet.OLEDB.4.0,提供程序字符串为”Text”。

数据源是包含文本文件的目录的完整路径名。schema.ini 文件(描述文本文件的结构)必须与此文本文件存在于相同的目录中。有关创建 schema.ini 文件的更多信息,请参见 Jet 数据库引擎文档。

–Create a linked server
EXEC sp_addlinkedserver txtsrv, ‘Jet 4.0’,
‘Microsoft.Jet.OLEDB.4.0’,
‘c:\data\distqry’,
NULL,
‘Text’
GO

–Set up login mappings
EXEC sp_addlinkedsrvlogin txtsrv, FALSE, Admin, NULL
GO

–List the tables in the linked server
EXEC sp_tables_ex txtsrv
GO

–Query one of the tables: file1#txt
–using a 4-part name
SELECT *
FROM txtsrv…[file1#txt]

I. 使用用于 DB2 的 Microsoft OLE DB 提供程序
下面的示例创建一台名为 DB2 的链接服务器,该服务器使用用于 DB2 的 Microsoft OLE DB 提供程序。

EXEC sp_addlinkedserver
@server=’DB2′,
@srvproduct=’Microsoft OLE DB Provider for DB2′,
@catalog=’DB2′,
@provider=’DB2OLEDB’,
@provstr=’Initial Catalog=PUBS;Data Source=DB2;HostCCSID=1252;Network Address=XYZ;Network Port=50000;Package Collection=admin;Default Schema=admin;’

 
方法三:
OPENQUERY
尽管查询可能返回多个结果集,但是 OPENQUERY 只返回第一个。

语法
OPENQUERY ( linked_server , ‘query’ )

参数
linked_server

一个标识符,表示链接的服务器的名称。

‘query’

在链接的服务器中执行的查询字符串。

注释
OPENQUERY 不接受参数变量。

示例
下面的示例利用用于 Oracle 的 Microsoft OLE DB 提供程序针对 Oracle 数据库创建一个名为 OracleSvr 链接的服务器。然后,该示例对此链接的服务器使用一个直接传递查询。

说明  本示例假定已经创建了一个名为 ORCLDB 的 Oracle 数据库别名。

EXEC sp_addlinkedserver ‘OracleSvr’,
‘Oracle 7.3’,
‘MSDAORA’,
‘ORCLDB’
GO
SELECT *
FROM OPENQUERY(OracleSvr, ‘SELECT name, id FROM joe.titles’)
GO

方法四:
OPENROWSET
包含访问 OLE DB 数据源中的远程数据所需的全部连接信息。当访问链接服务器中的表时,这种方法是一种替代方法,并且是一种使用 OLE DB 连接并访问远程数据的一次性的、特殊的方法。可以在查询的 FROM 子句中像引用表名那样引用 OPENROWSET 函数。依据 OLE DB 提供程序的能力,还可以将 OPENROWSET 函数引用为 INSERT、UPDATE 或 DELETE 语句的目标表。尽管查询可能返回多个结果集,然而 OPENROWSET 只返回第一个。

语法
OPENROWSET ( ‘provider_name’
, { ‘datasource’ ; ‘user_id’ ; ‘password’
| ‘provider_string’ }
, { [ catalog.] [ schema.] object
| ‘query’ }
)

示例
A. 将 OPENROWSET 与 SELECT 语句及用于 SQL Server 的 Microsoft OLE DB 提供程序一起使用
下面的示例使用用于 SQL Server 的 Microsoft OLE DB 提供程序访问 pubs 数据库中的 authors 表,该数据库在一个名为 seattle1 的远程服务器上。从 datasource、user_id 及 password 中初始化提供程序,并且使用 SELECT 语句定义返回的行集。

USE pubs
GO
SELECT a.*
FROM OPENROWSET(‘SQLOLEDB’,’seattle1′;’sa’;’MyPass’,
‘SELECT * FROM pubs.dbo.authors ORDER BY au_lname, au_fname’) AS a
GO

B. 将 OPENROWSET 与对象及用于 ODBC 的 OLE DB 提供程序一起使用
下面的示例使用用于 ODBC 的 OLE DB 提供程序以及 SQL Server ODBC 驱动程序访问 pubs 数据库中的 authors 表,该数据库在一个名为 seattle1 的远程服务器中。提供程序用在 ODBC 提供程序所用的 ODBC 语法中指定的 provider_string 进行初始化,定义返回的行集时使用 catalog.schema.object 语法。

USE pubs
GO
SELECT a.*
FROM OPENROWSET(‘MSDASQL’,
‘DRIVER={SQL Server};SERVER=seattle1;UID=sa;PWD=MyPass’,
pubs.dbo.authors) AS a
ORDER BY a.au_lname, a.au_fname
GO

C. 使用用于 Jet 的 Microsoft OLE DB 提供程序
下面的示例通过用于 Jet 的 Microsoft OLE DB 提供程序访问 Microsoft Access Northwind 数据库中的 orders 表。

 

说明  下面的示例假定已经安装了 Access。
USE pubs
GO
SELECT a.*
FROM OPENROWSET(‘Microsoft.Jet.OLEDB.4.0’,
‘c:\MSOffice\Access\Samples\northwind.mdb’;’admin’;’mypwd’, Orders)
AS a
GO

D. 使用 OPENROWSET 和 INNER JOIN 中的另一个表
下面的示例从本地 SQL Server Northwind 数据库的 customers 表中,以及存储在相同计算机上 Access Northwind 数据库的 orders 表中选择所有数据

 

说明  下面的示例假定已经安装了 Access。
USE pubs
GO
SELECT c.*, o.*
FROM Northwind.dbo.Customers AS c INNER JOIN
OPENROWSET(‘Microsoft.Jet.OLEDB.4.0’,
‘c:\MSOffice\Access\Samples\northwind.mdb’;’admin’;’mypwd’, Orders)
AS o
ON c.CustomerID = o.CustomerID
GO

 

http://www.cnblogs.com/daniel206/archive/2008/01/16/1041748.html

【转载】Mikrotik ROS hotspot 热点系统配置

分类: 信息化

HTML customizations

Summary

You can create a completely different set of servlet pages for each HotSpot server you have, specifying the directory it will be stored in html-directory property of a HotSpot server profile /ip hotspot profile. The default servlet pages are copied in the directory of your choice right after you create the profile. This directory can be accessed by connecting to the router with an FTP client. You can modify the pages as you like using the information from this section of the manual. Note that it is suggested to edit the files manually, as automated HTML editing tools may corrupt the pages by removing variables or other vital parts.

在服务器的Html目录下,建议采用手动编辑,自动工具可能会破坏页面结构,移除变量和其他的重要部分

Available Pages 

已经写好的页面

Main HTML servlet pages, which are shown to user:

  • redirect.html – redirects user to another url (for example, to login page)
  • 重定向的页面
  • login.html – login page shown to a user to ask for username and password. This page may take the following parameters:登陆页面,问用户要用户名和密码,包含了如下的一些字段
    • username – username
    • password – either plain-text password (in case of PAP authentication) or MD5 hash of chap-id variable, password and CHAP challenge (in case of CHAP authentication). This value is used as e-mail address for trial users
    • 密码部分:如果采用PAP方式则采用明文的内容,如果是CHAP方式则采用Chap-id变量,密码和CHAP挑战序列。如果是实用的话,这个参数将会是 用户的邮件地址
    • dst – original URL requested before the redirect. This will be opened on successfull login
    • 目标地址,也就是在重定向前的页面,如果登录成功将会跳转到这个页面
    • popup – whether to pop-up a status window on successfull login
    • 在登录成功后决定是否跳出一个状态页面
    • radius<id> – send the attribute identified with <id> in text string form to the RADIUS server (in case RADIUS authentication is used; lost otherwise)
    • 发送表单中id选项的属性给RADIUS服务器,如果没有启用RADIUS则丢弃这些属性
    • radius<id>u – send the attribute identified with <id> in unsigned integer form to the RADIUS server (in case RADIUS authentication is used; lost otherwise)
    • 和radius id 属性相同,只是发送的是无符号型的整数给radius服务器
    • radius<id>-<vnd-id> – send the attribute identified with <id> and vendor ID <vnd-id> in text string form to the RADIUS server (in case RADIUS authentication is used; lost otherwise)
    • 以字符串形式发送<id>属性还有<vendor-id>到RADIUS服务器,如果没有启用RADIUS仍然是丢弃这些属性
    • radius<id>-<vnd-id>u – send the attribute identified with <id> and vendor ID <vnd-id> in unsigned integer form to the RADIUS server (in case RADIUS authentication is used; lost otherwise)
  • md5.js – JavaScript for MD5 password hashing. Used together with http-chap login method
  • 这个是用JavaScript写的MD5密码哈希函数。和http-chap登录方式一起使用 调用可以使用  hexMD5(),作用和PHP的md5函数一样
  • alogin.html – page shown after client has logged in. It pops-up status page and redirects browser to originally requested page (before he/she was redirected to the HotSpot login page)
  • 用户登录后显示的页面。它弹出状态页面并且重定向浏览器到原来的请求页面
  • status.html – status page, shows statistics for the client. It is also able to display advertisements automatically
  • 状态页,为客户端显示状态信息。它也可以自动为用户显示广告
  • logout.html – logout page, shown after user is logged out. Shows final statistics about the finished session. This page may take the following additional parameters:
  • 注销页面:当用户注销后显示的页面,显示最终的统计信息。可以包含如下的参数:
    • erase-cookie – whether to erase cookies from the HotSpot server on logout (makes impossible to log in with cookie next time from the same browser, might be useful in multiuser environments)
    • 是否情况Hotspot服务器上的Cookie,这样的话其他用户就不能使用cookie进行自动登录了,一般在多用户情况下有用
  • error.html – error page, shown on fatal errors only
  • 错误页面,只显示致命错误信息

Some other pages are available as well, if more control is needed:

  • rlogin.html – page, which redirects client from some other URL to the login page, if authorization of the client is required to access that URL
  • 不太明白,反正是从其他URL重定向到登陆页面
  • rstatus.html – similarly to rlogin.html, only in case if the client is already logged in and the original URL is not known
  • 和rlogin很类似,比如用户已经登录了,但是还想登录,而且原来的URL根本不知道
  • radvert.html – redirects client to the scheduled advertisement link
  • 重定向用户到计划好的广告页面上
  • flogin.html – shown instead of login.html, if some error has happened (invalid username or password, for example)
  • 替代login.html的页面,如果发生一些错的时候(比如用户名或者密码不对)
  • fstatus.html – shown instead of redirect, if status page is requested, but client is not logged in
  • flogout.html – shown instead of redirect, if logout page is requested, but client is not logged in
  • 都是代替重定向页面的,都是用户没有登录,去尝试要求查看自己的状态或者尝试登出的情况

Serving Servlet Pages

The HotSpot servlet recognizes 5 different request types:

  1. request for a remote host
    • if user is logged in and advertisement is due to be displayed, radvert.html is displayed. This page makes redirect to the scheduled advertisment page
    • if user is logged in and advertisement is not scheduled for this user, the requested page is served
    • if user is not logged in, but the destination host is allowed by walled garden, then the request is also served
    • if user is not logged in, and the destination host is disallowed by walled garden, rlogin.html is displayed; if rlogin.html is not found, redirect.html is used to redirect to the login page
    • 能够识别的几种请求:
    • ①用户登录并且计划了广告页面,radvert.html显示;
    • ②用户登录,没有广告页,重定向到请求页。
    • ③用户没有登录,但是所请求的目标地址在walled garden区域
    • ④用户没有登录且请求位置没有被walled garden区域允许。如果rlogin.html找不到,redirect.html用于定向到登陆页
  2. request for “/” on the HotSpot host
    • if user is logged in, rstatus.html is displayed; if rstatus.html is not found, redirect.html is used to redirect to the status page
    • if user is not logged in, rlogin.html is displayed; if rlogin.html is not found, redirect.html is used to redirect to the login page
  3. request for “/login” page
    • if user has successfully logged in (or is already logged in), alogin.html is displayed; if alogin.html is not found, redirect.html is used to redirect to the originally requested page or the status page (in case, original destination page was not given)
    • if user is not logged in (username was not supplied, no error message appeared), login.html is showed
    • if login procedure has failed (error message is supplied), flogin.html is displayed; if flogin.html is not found, login.html is used
    • in case of fatal errors, error.html is showed
  4. request for “/status” page
    • if user is logged in, status.html is displayed
    • if user is not logged in, fstatus.html is displayed; if fstatus.html is not found, redirect.html is used to redirect to the login page
  5. request for ‘/logout’ page
    • if user is logged in, logout.html is displayed
    • if user is not logged in, flogout.html is displayed; if flogout.html is not found, redirect.html is used to redirect to the login page
Icon-note.png

Note: If it is not possible to meet a request using the pages stored on the router’s FTP server, Error 404 is displayed

There are many possibilities to customize what the HotSpot authentication pages look like:

  • The pages are easily modifiable. They are stored on the router’s FTP server in the directory you choose for the respective HotSpot server profile.
  • 页面都是很容易修改的,而且都在路由器的FTP目录下,你可以为每个Hotspot服务器选择各自的服务器配置文件
  • By changing the variables, which client sends to the HotSpot servlet, it is possible to reduce keyword count to one (username or password; for example, the client’s MAC address may be used as the other value) or even to zero (License Agreement; some predefined values general for all users or client’s MAC address may be used as username and password)
  • 通过修改客户端发送给服务器端程序的变量,可以把关键字减低到一个(比如在使用用户名或者密码的时候),也可以降到0(一些协议,比如使用客户端的MAC地址当做用户名和密码)
  • Registration may occur on a different server (for example, on a server that is able to charge Credit Cards). Client’s MAC address may be passed to it, so that this information need not be written in manually. After the registration, the server should change RADIUS database enabling client to log in for some amount of time.
  • 注册过程可能在另一台服务器上完成(比如能够对信用卡进行收取费用的服务器)。然后客户端的MAC可以传递给它,因此这些信息不需要手动来写。完成注册后,服务器应该能够改变RADIUS服务器,这样可以使客户能够登录一定的时间。

To insert variable in some place in HTML file, the $(var_name) syntax is used, where the “var_name” is the name of the variable (without quotes). This construction may be used in any HotSpot HTML file accessed as ‘/’, ‘/login’, ‘/status’ or ‘/logout’, as well as any text or HTML (.txt, .htm or .html) file stored on the HotSpot server (with the exception of traffic counters, which are available in status page only, and errorerror-origchap-idchap-challenge and popupvariables, which are available in login page only). For example, to show a link to the login page, following construction can be used:

在HTML中插入变量,可以使用 $(var_name)的语法形式。这样的语法可以在任何的HotSpot HTML文件中使用,只要这些文件能够通过/,/login,/status,/logout以及存储在HotSpot服务器上就能这样用【注意哪些traffic counter 只能在状态页status.html使用,那些 error,error-orig,chap-id,chap-challenge,popup变量只在登陆页有效】,

如果需要打登陆页的一个链接,可以这么写:

<a href="$(link-login)">login

Variables

All of the Servlet HTML pages use variables to show user specific values. Variable names appear only in the HTML source of the servlet pages – they are automatically replaced with the respective values by the HotSpot Servlet. For most variables there is an example of their possible value included in brackets. All the described variables are valid in all servlet pages, but some of them just might be empty at the time they are accesses (for example, there is no uptime before a user has logged in).

所有的服务HTML页都是使用变量显示用户特定的值。这些变量值只在服务端显示–他们自动被Hotspot服务器程序替换成各自的值。这里列出了变量和他们可能的值。这些描述的变量在服务器上都是可以使用的,但是他们中的一些在被访问的时候就是控制(比如,如果一个用户刚登陆就没有uptime)

List of available variables

Common server variables:

  • hostname – DNS name or IP address (if DNS name is not given) of the HotSpot Servlet (“hotspot.example.net”)
  • identity – RouterOS identity name (“MikroTik”)
  • login-by – authentication method used by user 认证的方式
  • plain-passwd – a “yes/no” representation of whether HTTP-PAP login method is allowed (“no”)
  • 是否允许采用HTTP-PAP方式登录,默认不允许
  • server-address – HotSpot server address (“10.5.50.1:80”) Hotspot服务器的地址,包含了端口号
  • ssl-login – a “yes/no” representation of whether HTTPS method was used to access that servlet page (“no”)
  • server-name – HotSpot server name (set in the /ip hotspot menu, as the name property)

Links:

General client information: 这些都是用户的信息变量

  • domain – domain name of the user (“example.com”)
  • interface-name – physical HotSpot interface name (in case of bridged interfaces, this will return the actual bridge port name)
  • ip – IP address of the client (“10.5.50.2”)
  • logged-in – “yes” if the user is logged in, otherwise – “no” (“yes”)
  • mac – MAC address of the user (“01:23:45:67:89:AB”)
  • trial – a “yes/no” representation of whether the user has access to trial time. If users trial time has expired, the value is “no”
  • username – the name of the user (“John”)
  • host-ip – client IP address from /ip hotspot host table

User status information:

  • idle-timeout – idle timeout (“20m” or “” if none)
  • idle-timeout-secs – idle timeout in seconds (“88” or “0” if there is such timeout)
  • limit-bytes-in – byte limit for send (“1000000” or “—” if there is no limit)
  • limit-bytes-out – byte limit for receive (“1000000” or “—” if there is no limit)
  • refresh-timeout – status page refresh timeout (“1m30s” or “” if none)
  • refresh-timeout-secs – status page refresh timeout in seconds (“90s” or “0” if none)
  • session-timeout – session time left for the user (“5h” or “” if none)
  • session-timeout-secs – session time left for the user, in seconds (“3475” or “0” if there is such timeout)
  • session-time-left – session time left for the user (“5h” or “” if none)
  • session-time-left-secs – session time left for the user, in seconds (“3475” or “0” if there is such timeout)
  • uptime – current session uptime (“10h2m33s”)
  • uptime-secs – current session uptime in seconds (“125”)

Traffic counters, which are available only in the status page:

  • bytes-in – number of bytes received from the user (“15423”)
  • bytes-in-nice – user-friendly form of number of bytes received from the user (“15423”)
  • bytes-out – number of bytes sent to the user (“11352”)
  • bytes-out-nice – user-friendly form of number of bytes sent to the user (“11352”)
  • packets-in – number of packets received from the user (“251”)
  • packets-out – number of packets sent to the user (“211”)
  • remain-bytes-in – remaining bytes until limit-bytes-in will be reached (“337465” or “—” if there is no limit)
  • remain-bytes-out – remaining bytes until limit-bytes-out will be reached (“124455” or “—” if there is no limit)

Miscellaneous variables:

  • session-id – value of ‘session-id’ parameter in the last request
  • var – value of ‘var’ parameter in the last request // 未知的变量
  • error – error message, if something failed (“invalid username or password”)
  • error-orig – original error message (without translations retrieved from errors.txt), if something failed (“invalid username or password”)
  • chap-id – value of chap ID (“\371”)
  • chap-challenge – value of chap challenge
  • 16位的挑战序列(“\357\015\330\013\021\234\145\245\303\253\142\246\133\175\375\316”)
  • popup – whether to pop-up checkbox (“true” or “false”) popup 是否进行弹窗
  • advert-pending – whether an advertisement is pending to be displayed (“yes” or “no”)
  • http-status – allows to set http status code and message
  • http-header – allows to add http header

RADIUS-related variables:

  • radius<id> – show the attribute identified with <id> in text string form (in case RADIUS authentication was used; “” otherwise)
  • radius<id>u – show the attribute identified with <id> in unsigned integer form (in case RADIUS authentication was used; “0” otherwise)
  • radius<id>-<vnd-id> – show the attribute identified with <id> and vendor ID <vnd-id> in text string form (in case RADIUS authentication was used; “” otherwise)
  • radius<id>-<vnd-id>u – show the attribute identified with <id> and vendor ID <vnd-id> in unsigned integer form (in case RADIUS authentication was used; “0” otherwise)

Working with variables

$(if <var_name>) statements can be used in theses pages. Following content will be included, if value of <var_name> will not be an empty string. It is an equivalent to $(if <var_name> != “”) It is possible to compare on equivalence as well: $(if <var_name> == <value>) These statements have effect until $(elif <var_name>), $(else) or $(endif). In general case it looks like this:

if 语句可以这么使用

$(if <var_name>)  如果变量不空的话就是真的,条件成立

$(if <var_name> != “”) 或者 $(if <var_name> == <value>) 

$(else) or $(endif)

some content, which will always be displayed
$(if username == john)
Hey, your username is john
$(elif username == dizzy)
Hello, Dizzy! How are you? Your administrator.
$(elif ip == 10.1.2.3)
You are sitting at that crappy computer, which is damn slow...
$(elif mac == 00:01:02:03:04:05)
This is an ethernet card, which was stolen few months ago...
$(else)
I don't know who you are, so lets live in peace.
$(endif)
other content, which will always be displayed

Only one of those expressions will be shown. Which one – depends on values of those variables for each client.

Redirects and custom Headers

新增加的重定向和自定义的头部

Starting from RouterOS 5.12 there are 2 new hotspot html page variables:

  • http-status – allows to set http status code and message
  • http-header – allows to add http header

Example:

	$(if http-status == 302)Hotspot login required $(endif)
	$(if http-header == "Location")$(link-redirect)$(endif)

In case if $(link-redirect) will evaluate to “http://192.168.88.1/login“, then HTTP response will look like:

HTTP/1.0 302 Hotspot login required
<regular HTTP headers>
Location: http://192.168.88.1/login

http-status syntax:

	$(if http-status == XYZ)HTTP_STATUS_MESSAGE$(endif)
  • XYZ – status code, should be 3 decimal digits, first one must not be 0
  • HTTP_STATUS_MESSAGE – any text, will follow status code in HTTP reply

In HTTP response it will be on first line and will look like:

HTTP/1.0 XYZ HTTP_STATUS_MESSAGE

http-header syntax:

	$(if http-header == HTTP_HEADER_NAME)HTTP_HEADER_VALUE$(endif)
  • HTTP_HEADER_NAME – name of the HTTP header to add
  • HTTP_HEADER_VALUE – value of HTTP header with name HTTP_HEADER_NAME

In HTTP response it will look like:

HTTP_HEADER_NAME: HTTP_HEADER_VALUE

All variables and conditional expressions within HTTP_HEADER_VALUE and HTTP_STATUS_MESSAGE are processed as usual.

In case multiple headers with the same name are added, then only the last one will be used (previous ones will be discarded). It allows to override regular HTTP headers (for example, Content-Type and Cache-Control).

如果多个具有相同名字的头部添加简历啊,只有最后一个添加的有效,前面的都会被丢弃,这样就可以覆盖常规的HTTP头部,比如Content-Type和Cache-Control

Customizing Error Messages

All error messages are stored in the errors.txt file within the respective HotSpot servlet directory. You can change and translate all these messages to your native language. To do so, edit the errors.txt file. You can also use variables in the messages. All instructions are given in that file.

自定义错误信息,所有的错误信息全部在各自的热点服务器errors.txt文件中,你可以改变或者翻译成为你的本地语言。你可以编辑那个txt文本文件,也可以在文本文件中使用变量。

Multiple Versions of HotSpot Pages

Multiple HotSpot page sets for the same HotSpot server are supported. They can be chosen by user (to select language) or automatically by JavaScript (to select PDA/regular version of HTML pages).

一个热点的Hotspot服务器可以有多个页面结合。他们可以被用户选择【比如语言】,或者被Javascript自动选择。

To utilize this feature, create subdirectories in HotSpot HTML directory, and place those HTML files, which are different, in that subdirectory.

为了做到这一点,首先创建子目录把这些不同的文件放到那里面去。

For example, to translate everything in Latvian, subdirectory “lv” can be created with login.html, logout.html, status.html, alogin.html, radvert.html and errors.txt files, which are translated into Latvian.

如果需要做一个拉脱维亚语的登录界面,那么就创建一个lv的子目录,然后将翻译好的 login.html, logout.html, status.html, alogin.html, radvert.html and errors.txt 文件放到lv目录下面。

If the requested HTML page can not be found in the requested subdirectory, the corresponding HTML file from the main directory will be used. Then main login.html file would contain link to “/lv/login?dst=$(link-orig-esc)”, which then displays Latvian version of login page: <a href=”/lv/login?dst=$(link-orig-esc)”>Latviski . And Latvian version would contain link to English version: <a href=”/login?dst=$(link-orig-esc)”>English

Another way of referencing directories is to specify ‘target’ variable:

        <a href="$(link-login-only)?dst=$(link-orig-esc)&target=lv">Latviski
        <a href="$(link-login-only)?dst=$(link-orig-esc)&target=%2F">English

After preferred directory has been selected (for example, “lv”), all links to local HotSpot pages will contain that path (for example, $(link-status) = “http://hotspot.mt.lv/lv/status“). So, if all HotSpot pages reference links using “$(link-xxx)” variables, then no more changes are to be made – each client will stay within the selected directory all the time.

Misc

If you want to use HTTP-CHAP authentication method it is supposed that you include the doLogin() function (which references to the md5.js which must be already loaded) before the Submit action of the login form. Otherwise, CHAP login will fail.

The resulting password to be sent to the HotSpot gateway in case of HTTP-CHAP method, is formed MD5-hashing the concatenation of the following: chap-id, the password of the user and chap-challenge (in the given order)

In case variables are to be used in link directly, then they must be escaped accordingly. For example, in login page,<a href=”https://login.example.com/login?mac=$(mac)&user=$(username)”>link will not work as intended, if username will be “123&456=1 2”. In this case instead of $(user), its escaped version must be used: $(user-esc): <a href=”https://login.server.serv/login?mac=$(mac-esc)&user=$(user-esc)”>link. Now the same username will be converted to “123%26456%3D1+2”, which is the valid representation of “123&456=1 2” in URL. This trick may be used with any variables, not only with $(username).

There is a boolean parameter “erase-cookie” to the logout page, which may be either “on” or “true” to delete user cookie on logout (so that the user would not be automatically logged on when he/she opens a browser next time.

Examples

With basic HTML language knowledge and the examples below it should be easy to implement the ideas described above.

  • To provide predefined value as username, in login.html change:
<type="text" value="$(username)>

to this line:

<input type="hidden" name="username" value="hsuser">

(where hsuser is the username you are providing)

  • To provide predefined value as password, in login.html change:
<input type="password">

to this line:

<input type="hidden" name="password" value="hspass">

(where hspass is the password you are providing)

  • To send client’s MAC address to a registration server in form of:

https://www.example.com/register.html?mac=XX:XX:XX:XX:XX:XX

change the Login button link in login.html to:

https://www.example.com/register.html?mac=$(mac)

(you should correct the link to point to your server)

  • To show a banner after user login, in alogin.html after

$(if popup == ‘true’) add the following line:

open('http://www.example.com/your-banner-page.html', 'my-banner-name','');

(you should correct the link to point to the page you want to show)

  • To choose different page shown after login, in login.html change:
<input type="hidden" name="dst" value="$(link-orig)">

to this line:

<input type="hidden" name="dst" value="http://www.example.com">

(you should correct the link to point to your server)

  • To erase the cookie on logoff, in the page containing link to the logout (for example, in status.html) change:
open('$(link-logout)', 'hotspot_logout', ...

to this:

open('$(link-logout)?erase-cookie=on', 'hotspot_logout', ...

or alternatively add this line:

<input type="hidden" name="erase-cookie" value="on">

before this one:

<input type="submit" value="log off">

An another example is making HotSpot to authenticate on a remote server (which may, for example, perform creditcard charging):

  • Allow direct access to the external server in walled-garden (either HTTP-based, or IP-based)
  • Modify login page of the HotSpot servlet to redirect to the external authentication server. The external server should modify RADIUS database as needed

Here is an example of such a login page to put on the HotSpot router (it is redirecting tohttps://auth.example.com/login.php, replace with the actual address of an external authentication server):

<html>
<title>...</title>
<body>
<form name="redirect" action="https://auth.example.com/login.php" method="post">
<input type="hidden" name="mac" value="$(mac)">
<input type="hidden" name="ip" value="$(ip)">
<input type="hidden" name="username" value="$(username)">
<input type="hidden" name="link-login" value="$(link-login)">
<input type="hidden" name="link-orig" value="$(link-orig)">
<input type="hidden" name="error" value="$(error)">
</form>
<script language="JavaScript">
<!--
	document.redirect.submit();
//-->
</script>
</body>
</html>
          
  • The external server can log in a HotSpot client by redirecting it back to the original HotSpot servlet login page, specifying the correct username and password

Here is an example of such a page (it is redirecting to https://hotspot.example.com/login, replace with the actual address of a HotSpot router; also, it is displaying www.mikrotik.com after successful login, replace with what needed):

<html>
<title>Hotspot login page</title>
<body>
<form name="login" action="https://hotspot.example.com/login" method="post">
<input type="text" name="username" value="demo">
<input type="password" name="password" value="none">
<input type="hidden" name="domain" value="">
<input type="hidden" name="dst" value="http://www.mikrotik.com/">
<input type="submit" name="login" value="log in">
</form>
</body>
</html>
          
  • Hotspot will ask RADIUS server whether to allow the login or not. If not allowed, alogin.html page will be displayed (it can be modified to do anything). If not allowed, flogin.html (or login.html) page will be displayed, which will redirect client back to the external authentication server.
Icon-note.png

Note: as shown in these examples, HTTPS protocol and POST method can be used to secure communications.

Firewall customizations

Summary

Apart from the obvious dynamic entries in the /ip hotspot submenu itself (like hosts and active users), some additional rules are added in the firewall tables when activating a HotSpot service. Unlike RouterOS version 2.8, there are relatively few firewall rules added in the firewall as the main job is made by the one-to-one NAT algorithm.

NAT

From /ip firewall nat print dynamic command, you can get something like this (comments follow after each of the rules):

 0 D chain=dstnat action=jump jump-target=hotspot hotspot=from-client

Putting all HotSpot-related tasks for packets from all HotSpot clients into a separate chain.

 1 I chain=hotspot action=jump jump-target=pre-hotspot

Any actions that should be done before HotSpot rules apply, should be put in the pre-hotspot chain. This chain is under full administrator control and does not contain any rules set by the system, hence the invalid jump rule (as the chain does not have any rules by default).

 2 D chain=hotspot action=redirect to-ports=64872 dst-port=53 protocol=udp 
 3 D chain=hotspot action=redirect to-ports=64872 dst-port=53 protocol=tcp 

Redirect all DNS requests to the HotSpot service. The 64872 port provides DNS service for all HotSpot users. If you want HotSpot server to listen also to another port, add rules here the same way, changing dst-port property.

 4 D chain=hotspot action=redirect to-ports=64873 hotspot=local-dst dst-port=80
     protocol=tcp

Redirect all HTTP login requests to the HTTP login servlet. The 64873 is HotSpot HTTP servlet port.

 5 D chain=hotspot action=redirect to-ports=64875 hotspot=local-dst dst-port=443
     protocol=tcp

Redirect all HTTPS login requests to the HTTPS login servlet. The 64875 is HotSpot HTTPS servlet port.

 6 D chain=hotspot action=jump jump-target=hs-unauth hotspot=!auth protocol=tcp

All other packets except DNS and login requests from unauthorized clients should pass through the hs-unauth chain.

 7 D chain=hotspot action=jump jump-target=hs-auth hotspot=auth protocol=tcp

And packets from the authorized clients – through the hs-auth chain.

 8 D ;;; www.mikrotik.com
     chain=hs-unauth action=return dst-address=66.228.113.26 dst-port=80 protocol=tcp

First in the hs-unauth chain is put everything that affects TCP protocol in the /ip hotspot walled-garden ip submenu (i.e., everything where either protocol is not set, or set to TCP). Here we are excluding www.mikrotik.com from being redirected to the login page.

 9 D chain=hs-unauth action=redirect to-ports=64874 dst-port=80 protocol=tcp

All other HTTP requests are redirected to the Walled Garden proxy server which listens the 64874 port. If there is an allow entry in the /ip hotspot walled-garden menu for an HTTP request, it is being forwarded to the destination. Otherwise, the request will be automatically redirected to the HotSpot login servlet (port 64873).

10 D chain=hs-unauth action=redirect to-ports=64874 dst-port=3128 protocol=tcp 
11 D chain=hs-unauth action=redirect to-ports=64874 dst-port=8080 protocol=tcp 

HotSpot by default assumes that only these ports may be used for HTTP proxy requests. These two entries are used to “catch” client requests to unknown proxies (you can add more rules here for other ports). I.e., to make it possible for the clients with unknown proxy settings to work with the HotSpot system. This feature is called “Universal Proxy”. If it is detected that a client is using some proxy server, the system will automatically mark that packets with the http hotspot mark to work around the unknown proxy problem, as we will see later on. Note that the port used (64874) is the same as for HTTP requests in the rule #9 (so both HTTP and HTTP proxy requests are processed by the same code).

12 D chain=hs-unauth action=redirect to-ports=64875 dst-port=443 protocol=tcp

HTTPS proxy is listening on the 64875 port.

13 I chain=hs-unauth action=jump jump-target=hs-smtp dst-port=25 protocol=tcp

Redirect for SMTP protocol may also be defined in the HotSpot configuration. In case it is, a redirect rule will be put in the hs-smtp chain. This is done so that users with unknown SMTP configuration would be able to send their mail through the service provider’s (your) SMTP server instead of going to the [possibly unavailable outside their network of origin] SMTP server users have configured on their computers. The chain is empty by default, hence the invalid jump rule.

14 D chain=hs-auth action=redirect to-ports=64874 hotspot=http protocol=tcp

Providing HTTP proxy service for authorized users. Authenticated user requests may need to be subject to transparent proxying (the “Universal Proxy” technique and advertisement feature). This http mark is put automatically on the HTTP proxy requests to the servers detected by the HotSpot HTTP proxy (the one that is listening on the 64874 port) as HTTP proxy requests for unknown proxy servers. This is done so that users that have some proxy settings would use the HotSpot gateway instead of the [possibly unavailable outside their network of origin] proxy server users have configured in their computers. This mark is also applied when advertisement is due to be shown to the user, as well as on any HTTP requests done form the users whose profile is configured to transparently proxy their requests.

15 I chain=hs-auth action=jump jump-target=hs-smtp dst-port=25 protocol=tcp

Providing SMTP proxy for authorized users (the same as in rule #13).

Packet Filtering

From /ip firewall filter print dynamic command, you can get something like this (comments follow after each of the rules):

 0 D chain=forward action=jump jump-target=hs-unauth hotspot=from-client,!auth

Any packet that traverse the router from an unauthorized client will be sent to the hs-unauth chain. The hs-unauth implements the IP-based Walled Garden filter.

 1 D chain=forward action=jump jump-target=hs-unauth-to hotspot=to-client,!auth

Everything that comes to clients through the router, gets redirected to another chain, called hs-unauth-to. This chain should reject unauthorized requests to the clients.

 2 D chain=input action=jump jump-target=hs-input hotspot=from-client

Everything that comes from clients to the router itself, gets to yet another chain, called hs-input.

 3 I chain=hs-input action=jump jump-target=pre-hs-input

Before proceeding with [predefined] dynamic rules, the packet gets to the administratively controlled pre-hs-inputchain, which is empty by default, hence the invalid state of the jump rule.

 4 D chain=hs-input action=accept dst-port=64872 protocol=udp 
 5 D chain=hs-input action=accept dst-port=64872-64875 protocol=tcp 

Allow client access to the local authentication and proxy services (as described earlier).

 6 D chain=hs-input action=jump jump-target=hs-unauth hotspot=!auth

All other traffic from unauthorized clients to the router itself will be treated the same way as the traffic traversing the routers.

 7 D chain=hs-unauth action=return protocol=icmp
 8 D ;;; www.mikrotik.com
     chain=hs-unauth action=return dst-address=66.228.113.26 dst-port=80 protocol=tcp

Unlike NAT table where only TCP-protocol related Walled Garden entries were added, in the packet filter hs-unauth chain is added everything you have set in the  /ip hotspot walled-garden ip menu. That is why although you have seen only one entry in the NAT table, there are two rules here.

 9 D chain=hs-unauth action=reject reject-with=tcp-reset protocol=tcp
10 D chain=hs-unauth action=reject reject-with=icmp-net-prohibited

Everything else that has not been while-listed by the Walled Garden will be rejected. Note usage of TCP Reset for rejecting TCP connections.

11 D chain=hs-unauth-to action=return protocol=icmp
12 D ;;; www.mikrotik.com
     chain=hs-unauth-to action=return src-address=66.228.113.26 src-port=80 protocol=tcp

Same action as in rules #7 and #8 is performed for the packets destined to the clients (chain hs-unauth-to) as well.

13 D chain=hs-unauth-to action=reject reject-with=icmp-host-prohibited

Reject all packets to the clients with ICMP reject message.

 

http://blog.chinaunix.net/uid-21126994-id-3839046.html

【转载】RouterBOARD安装与复位操作

前几天看到一个网友提的问题,关于RouterBOARD如何复位,就这个问题,我写了以下关于RouterBOARD安装和复位操作,普及下RouterBOARD的知识。

RouterBOARD是硬件化的RouterOS,当RouterBOARD的RouterOS密码丢失或配置错误后,一般只能通过Netinstall重装RouterOS系统或者使用RouterBOARD的复位跳针(或复位圆孔),你需要在设备启动时短路接口,直到启动完成,便可复位RouterOS。

如下图是RB411主板的金属复位片。注意:旁边白色的按钮,则是固件复位按钮,而非RouterOS的复位按钮。

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

  下面是通过一个十字螺丝刀复位的操作,你也可以用其他金属工具将两个铜片短路。

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

下面是RB2011USA-2HnD的复位按钮,靠外侧的是固件复位按钮(启动时长按固件复位按钮,可以通过ethernet方式引导),后面圆形的是RouterOS复位接口(在启动前短路这个复位接口,直到启动完成,RouterOS软件就会复位)。

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

  早期型号复位下面的图片是RB133复位,我们使用的是跳针,即需要跳线帽进行RouterOS配置的复位:

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

  注意,当你复位完成后,不要忘了把跳线帽移除,否则会出现重启后再次复位配置。提示:关于RouterBOARD设备介绍可以参考《RouterOS网络教程》一书。通过Netinstall安装和复位RouterOS

Netinstall早期需要通过console口连接进入RouterBOARD的“BIOS”修改引导方式为ethernet(以太网引导),即通过使用netinstall工具进行网络安装,现在RouterBOARD提供了新的方式可以在没有console口的情况安装,一种是winbox设置引导,一种是长按固件复位按钮引导。

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

首先我们需要准备netinstall工具和RouterOS安装包,这些工具盒软件我们可以从http://www.mikrotik.com/download下载,在下载页面选择你需要的RouterOS对应硬件型号和软件版本,我这里掩饰用的是RB751U,所以选择的是mispbe,并且在这个版本中有多个选择,如果用于netinstall,选择upgrade package。

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

 

准备好工具和软件后,现在需要电脑和RB设备通过网线连接,将网线接在RB设备的Ether1上,然后进入winbox选择system->routerboard->settings修改重启后的引导方式。如下图:

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

  这里我们选择try-ethernet-once-then-nand,即通过ethernet引导一次,如果失败就选择nand引导 以上配置完成后,启动netinstall,注意如果你是windows vista或7、8系统,第一次启动这个软件,需要允许它网络连接,建议关闭掉其他在运行的软件,避免影响netinstall软件安装。

启动netinstall软件,我们首先配置Net booting,选择Boot Server Enabled,设置网络连接ip地址,这个地址一定要和你的电脑的网卡在同一网络段中,如我的电脑是192.168.88.3/24,配置给Netinstall分配给RB的地址是192.168.88.2

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

设置好以上参数,就可以通过命令重启RouterBOARD,重启后RouterBOARD会自动搜索以太网引导服务器,找到后会在netinstall中显示设备型号和mac地址,显示Ready状态,你指定好安装包路径后,会自动选择设备的安装包,如下图

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

之后,我们点击install按钮,首先netinstall会对RouterBOARD的存储进行分区和格式化

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

之后开始传输安装包,进行安装:

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

安装完成后显示installation finished successfully

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

  退出netinstall,RouterBOARD设备重启,这样复位工作就完成。忘记密码

当然遇到忘记RouterOS登陆密码,那就需要使用另外一种方式,一个是之前提到到圆形复位铜片,但这个对于有些安装外壳的RouterBOARD不太方便,所以需要另一种方式,即在RouterBOARD启动时按照固件复位按钮,采用netinstall引导安装。

RouterBOARD安装与复位操作 - athlon_sds - YuSong的世界

 

如上图,RB751U的固件复位按钮接口(不同RB设备的固件复位按钮不同),启动时长按,直到netinstall找到并显示设备信息,便可以进行安装复位,操作和之前一样。

 

http://blog.163.com/athlon_sds/blog/static/931614232012109105279/

【转载】RouterOS新功能CAPs【ROS的AC控制功能】可以无缝网络漫游哦

MikroTik在14年的意大利MUM上,除了发布新的CCR、CRS和RB产品,还公布了一个新的功能——CAPs即 Controlled Access Point system Manager(CAPsMAN),通俗点说,它就是一个AP控制器功能插件,可以将任何一台RouterOS变为AP控制器,只要安装CAP的功能包(集成在wireless-fp功能包中)

它的功能就是用于集中控制你所有的RouterOS AP设备,以便快速部署大型无线网络【可以做到类似信号漫游,无缝切换,集中设置】
– CAPs管理与AP之间连接能同时工作中二层和三层网络,也就是如果你想把AC端放在某一个地方也可以集中管理远距离的AP设备的SSID,信道,密码,等配置信息。

在CAPs系统中包含数个AP(CAPsMAN代表集中管理系统,CAP代表被管理AP),CAPs为他们提供无线连接管理,维护客户端验证和数据转发
当CAP被控制管理,将建立与管理端的配置连接,通常由AP执行的如AP访问控制,客户端验证,现在交由管理端控制。CAP仅仅是维护无线连接层面的加密和解码,根据配置,数据将转发到管理端为集中处理或转发到本地的CAP。

下面我就来演示一下建立一个简单的CAPsMan管理环境

  1. 准备1台RouterOS6.11版本或更高的系统作为AC端,用于控制其他RouterOS【6.11或更高版本,要和服务端一致】的无线网卡,但是不能控制自己的无线哦
  2. CAPs功能包可以在这里下载
  3. CAPsMAN的功能包可以独立安装到任何平台的RouterOS v6.11以上版本,CAPsMAN功能还在测试中,所以功能包为独立的wireless-fp-6.11-mipsbe.npk,安装后将替代原理的wireless功能包,功能包升级后wireless功能包被自动禁用,wireless-fp启用(该功能以后可能会合并),如下图:
  4. 1开启Enable后reboot设备
  5. AC控制器端设置方法下,开启这个功能后进行配置
  6. 2
  7. 下面开始配置,配置名称,模式默认只能选AP,还有SSID名称,信号,安全方式等,做成一个个配置供后面选择和切换。
  8. 3 4
  9. 上面的AC端配置完成后,配置AP端如图:点击无线–CAP,开启,interface是选择管理的无线网卡,Discovery Interface是连接到AC端的网口设备【如果是EoIP就选之】,下面那个10.0.0.254是我AC端设备的IP地址,默认可以不填他就优先用MAC进行对接。
  10. 5
  11. 完成对接之后,在AC端可以看到这个设备,你可以修改设备标识。
  12. 6
  13. 我建立一个Bridge,然后把控制接口和这个设备放在一起,如果你加入了多个AP设备,那就全部添加到这个桥里面,然后把DHCP或者其它服务分配给这个桥,他们每个AP就像接了个网线到你这里一样了。
  14. 8

7

 

留意哦:这里如果你有2个或以上的AP端设备加入后,他们的信号名称是一样的哦,得到的效果就像无缝漫游一样,只要在多个设备覆盖范围内,就可以随意自动无缝切换不掉线。

甚至如果你是整条街都铺满这个设备,还可以通过外网建立EoIP来建立虚拟隧道来统一远程接入和管理。

  1. 即CAPsMAN为CAP管理器菜单,CAP为被管理网卡菜单
    CAP连接到CAPsMAN
    CAPsMAN系统要为无线网络提供管理控制,需要至少一个CAP必须与CAPsMAN建立连接。一个管理连接建立可以使用MAC或IP层协议和安全的DTLS,通常一个CAP能传递客户端数据连接到管理器,但数据连接并不安全,因此需要考虑数据安全的加密,例如IPSec或加密隧道。
    CAP 连接到CAPsMAN 能建立连接使用以下两种传输协议:
    MAC层连接特性:
    ? – 没有在CAP上配置IP地址
    ? – CAP和CAPsMAN必须在相同二层网络中,二层交换或虚拟网络(二层隧道,例如EoIP)
    IP层连接(UDP)特性:
    ? – 如果需要可穿透NAT
    ? – CAP必须通过IP协议连接到CAPsMAN
    根据网络情况,如果CAP与CAPsMAN没有在相同二层网络,必须为CAPsMAN分配IP地址,且两端路由可达。
    建立连接规则
    当可以获取的CAPsMAN列表建立,CAP选择一个CAPsMAN基于以下规则:
    § 如果 caps-man-names 参数指定管理名称(CAPsMAN的/system identity)CAP将优先选择。如果该参数为空,将连接其他CAPsMAN。
    § MAC层连接优先级高于IP层连接
    当管理器被选择后,CAP尝试建立DTLS连接。
    CAPsMAN与CAP实例
    下面是一个简单的CAP实例,假设我们网络中只有一个CAPsMAN和一个CAP,他们之间通过二层网络连接。
    4

参考:http://blog.163.com/athlon_sds/blog/static/9316142320143392456137/

[转载]RouterOS CAPs 简单介绍与配置

RouterOS新功能CAPs, Controlled Access Point system Manager(CAPsMAN),即AP控制系统。也就是我们经常说的AP控制器,可以将任何一台RouterOS变为AP控制器,只要安装CAP的功能包(集成在wireless-fp功能包中)。

 
对于CAPsMAN来说是AP控制器,CAP是被控制AP,即我们常说的的胖AP和瘦AP,只是RouterBOARD安装CAP功能包后,可以根据需要定义是胖AP或瘦AP。
 

RouterOS CAPs功能包

CAPsMAN的功能包可以独立安装到任何平台的RouterOS v6.11以上版本,CAPsMAN功能还在测试中,所以功能包为独立的wireless-fp-6.11-mipsbe.npk,安装后将替代原理的wireless功能包,功能包升级后wireless功能包被自动禁用,wireless-fp启用(该功能以后可能会合并),如下图:

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

我们可以在winbox中看到CAPsMAN菜单:

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界
 

 在winbox的wireless菜单,可以看到CAP选项

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界
 

CAPsMANCAP管理器菜单,CAP为被管理网卡菜单

CAP连接到CAPsMAN

CAPsMAN系统要为无线网络提供管理控制,需要至少一个CAP必须与CAPsMAN建立连接。一个管理连接建立可以使用MAC或IP层协议和安全的DTLS,通常一个CAP能传递客户端数据连接到管理器,但数据连接并不安全,因此需要考虑数据安全的加密,例如IPSec或加密隧道。

CAP 连接到CAPsMAN 能建立连接使用以下两种传输协议:

MAC层连接特性:

?   – 没有在CAP上配置IP地址

?   – CAP和CAPsMAN必须在相同二层网络中,二层交换或虚拟网络(二层隧道,例如EoIP)

IP层连接(UDP)特性:

?   – 如果需要可穿透NAT

?   – CAP必须通过IP协议连接到CAPsMAN

根据网络情况,如果CAP与CAPsMAN没有在相同二层网络,必须为CAPsMAN分配IP地址,且两端路由可达。

建立连接规则

当可以获取的CAPsMAN列表建立,CAP选择一个CAPsMAN基于以下规则:

§  如果 caps-man-names 参数指定管理名称(CAPsMAN的/system identityCAP将优先选择。如果该参数为空,将连接其他CAPsMAN

§  MAC层连接优先级高于IP层连接

 

当管理器被选择后,CAP尝试建立DTLS连接。

 

CAPsMANCAP实例

下面是一个简单的CAP实例,假设我们网络中只有一个CAPsMAN和一个CAP,他们之间通过二层网络连接。

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

    之前的介绍CAPCAPsMAN连接,可以通过MAC层和IP层连接,CAP也具备自动搜索CAPsMAN功能,也可以通过caps-man-names连接,这里CAPsMANCAP连接基于二层,且这个二层网络仅有一台CAPsMAN,所以我们的建立变的简单。

之前的介绍CAPCAPsMAN连接,可以通过MAC层和IP层连接,CAP也具备自动搜索CAPsMAN功能,也可以通过caps-man-names连接,这里CAPsMANCAP连接基于二层,且这个二层网络仅有一台CAPsMAN,所以我们的建立变的简单。

启用CAPsMAN

由于CAPsMANCAP基于二层网络互连,且仅只有一个CAPsMAN,所以我们仅启用CAPsMANCAPsMAN功能可以安装到任何RouterOS平台上,我用RB750作为CAPsMAN管理器。

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

启用CAPsMAN后,需要将CAP连接到CAPsMAN上,这里我们是一台RB411,通过ether1连接到RB750,首先我们需要在CAP上开启功能,进入wireless选项,选择CAP菜单

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

进入CAP菜单后,我们开启CAP功能,选择wlan1为被管理网卡,探测CAPsMAN网卡为ether1

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

配置完成后,CAP开始自动搜索二层网络内的CAPsMAN管理器,大约几秒钟后CAP连接上CAPsMAN,如下图

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

但当前标识状态看cap3MBIM代表主设备,B代表被绑定,I代表未激活,因为cap3没有配置无线相关参数,我们再来看看CAP的状态

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

 从上图中可以看到managed by CAPsMAN,即被CAPsMAN管理,wlan1无线网卡处于禁用状态,是无法被本地的RouterOS管理。

跟着我们要为CAPsMAN连接的CAP配置无线参数,连接的wlan1是一张802.11bg网卡,我们需要在CAPsMAN配置相关的bg无线参数,首先定义频道,取名2412,频段2ghz-b/g,发射频率2412MHz,频宽20MHz

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

定义配置规则组,进入configurations下,添加一个规则组取名ap1modapSSID设置为yus

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

选择Channel设置频率,我们将之前设置的2412频率选择上

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

当配置规则组完成后,返回interface菜单下,选择cap3,进入wireless菜单,直接选择configurationap1

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

配置完成后,我们可以看下cap3的状态,已经没有I标识

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

 再看看CAP状态,清楚的显示wlan1的频率和SSID等信息

 RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

通过电脑搜索到yus的无线信号,没有设置加密所以不安全

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

 这样基本的无线已经配置完成,但对于这个无线的CAPsMAN系统仅仅完成一半,通常情况下我们需要为客户端分配IP,不管是热点认证还是直接上网,都要让客户端自动获取IP(特殊环境除外,如固定IP),下一步肯定是要做DHCP服务器,

DHCP服务器配置

DHCP服务器不是在CAP上做,而是在CAPsMAN上,因为CAPwlan1网卡不在接受本地RouterOS的管理,已经从属于CAPsMANRouterOS上,cap3已经是CAPsMANRouterOS的一张虚拟无线网卡,所以我们的DHCP服务器是在CAPsMAN上完成。

DHCP配置这里就简单过下:

ip address中为cap3分配ip地址192.168.20.1/24

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

 在ip pool建立地址池

 RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

建立DHCP服务器到cap3

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

 设置DHCP网络获取的网关、子网和DNS

RouterOS CAPs 简单介绍与配置 - athlon_sds - YuSong的世界

DHCP建立完成后,直接可以获取到cap3无线分配的IP地址

http://blog.163.com/athlon_sds/blog/static/9316142320143392456137/