简介
目的:portal服务器向AC设备发送数据后,会得到AC设备的响应。
文章结构
- AC配置
- portal服务器的数据封装
- 测试
AC配置
配置协议对接
ip hw-portal-server source-interface vlan 20 port 2000
aaa rfc-3576-client 192.168.1.138
key 123456789
192.168.1.138 为portal服务器的IP地址
key为portal服务器与AC设备对接是的secret
配置captive-portal
aaa authentication captive-portal inter_captive_portal
rfc-3576-client 192.168.1.138
到这里就可以从portal服务器上向AC的2000端口发送请求
portal服务器的数据封装
说明
portal设备与AC交互的包类型使用的是华为portal2.0协议,所以需要先对portal2.0协议进行封装。参考博客点这里
使用UDP协议来发送报文,所以还需要UDP的协议的知识参考博客点这里
测试
测试步骤
运行测试代码,若有打印出“获取Challenge成功”或“获取Challenge失败”则表示交互成功
package socket;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import tlv.Attr;
import tlv.TlvHwBean;
import tlv.TlvTools;
import tlv.TlvBean;
public class ChatterClient extends Thread {
private DatagramSocket s;
private InetAddress hostAddress;
private byte[] buf = new byte[1000];
private DatagramPacket dp = new DatagramPacket(buf, buf.length);
private byte[] bufRe = new byte[1000];
private DatagramPacket dpRe = new DatagramPacket(bufRe, bufRe.length);
private int id;
private String ip;
private int port;
private String userIp;
private int serialNo;
public void run() {
try {
s.send(Dgram.toDatagram(HwReqChallenge(), hostAddress, port));
s.receive(dp);
TlvHwBean b = parseHw(dp.getData());
if(b.getErrCode()==0){
System.out.println("获取Challenge成功");
}else{
System.out.println("获取Challenge失败");
}
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
/**
* 生成Challenge的请求
* @return
*/
public byte[] HwReqChallenge() {
List<Attr> attr = new ArrayList<Attr>();
Attr a = new Attr(1, "zyt@siganet");
Attr b = new Attr(2, "siganet");
attr.add(a);
attr.add(b);
return TlvTools.buildHwReqChallenge(serialNo, userIp, attr);
}
/**
* 生成认证请求
* @param reqId
* @return
*/
private byte[] HwReqAuth(int reqId){
List<Attr> attr = new ArrayList<Attr>();
Attr a = new Attr(1, "zyt@siganet");
Attr b = new Attr(2, "siganet");
attr.add(a);
attr.add(b);
return TlvTools.buildHwReqAuth(serialNo, reqId, userIp, attr);
}
/**
* 将byte[]转为TlvHwBean
* @param a
* @return
*/
private TlvHwBean parseHw(byte[] a){
return TlvTools.parseHw(a);
}
/**
* 用于生成随机的serialNo
* @param max
* @param min
* @return
*/
private int getRandom(int max, int min) {
Random r = new Random();
int s = r.nextInt(max) % (max - min + 1) + min;
return s;
}
/**
*
* @param ip AC的ip地址
* @param port AC监听的端口
* @param userIp 用户内网ip
*/
public ChatterClient(String ip, int port,String userIp) {
this.ip = ip;
this.port = port;
this.userIp = userIp;
this.serialNo = getRandom(65025, 0);
try {
s = new DatagramSocket();
hostAddress = InetAddress.getByName(ip);
} catch (UnknownHostException e) {
System.err.println("Cannot find host");
System.exit(1);
} catch (SocketException e) {
System.err.println("Can't open socket");
e.printStackTrace();
System.exit(1);
}
System.out.println("请求开始");
}
public static void main(String[] args) {
// 西加云杉设备
// “192.168.1.199”为AC设备的IP地址
// “2000”为AC设备开放的认证端口
// “192.168.1.200”为移动端的Ip
new ChatterClient("192.168.1.199", 2000,"192.168.1.200").start();
}
}