Автор статьи будет на следующей неделе только
Там есть нюансы с коммутаторами: они по-разному ставят опцию remoteId, как я понял.
Данный клиент почему-то сделал динамическим кодом предобработки так, что от remoteId остаётся только последний байт.
Т.к. в предобработке RADIUS пакета в UserName добавляется после : послений бай, а в предобработке DHCP пакета - remoteId опция также обрезается.
Вот код его процессора протокола.
Код:
package ru.clink.bgbilling.module.inet.device.redback;
import org.apache.log4j.Logger;
import ru.bitel.bgbilling.kernel.network.dhcp.*;
import ru.bitel.bgbilling.kernel.network.radius.*;
import ru.bitel.bgbilling.modules.inet.access.sa.*;
import ru.bitel.common.*;
import ru.bitel.common.sql.*;
public class SmartEdgeProtocolHandler
extends ProtocolHandlerAdapter
{
private static final Logger log = Logger.getLogger( SmartEdgeServiceActivator.class );
@Override
public void preprocessAccessRequest( RadiusPacket request, RadiusPacket response, ConnectionSet connectionSet )
throws Exception
{
String macAddr = request.getStringAttribute( 2352, 145, null );
byte[] remoteId = request.getByteAttribute( 2352, 96, null );
byte[] circuitId = request.getByteAttribute( 2352, 97, null );
if( macAddr != null && remoteId != null && circuitId != null )
{
String callingStation = macAddr.replaceAll( "\\-", "" );
String userName = "";
if (remoteId.length == 8) {
log.info( "Format of Option 82 is D-link" );
userName = Utils.bytesToHexString( remoteId ).substring(4, 16) + ":" + Utils.bytesToHexString( circuitId ).substring(10, 12);
}
if (remoteId.length == 11) {
log.info( "Format of Option 82 is Eltex" );
userName = Utils.bytesToHexString( remoteId ).substring(10, 22) + Utils.bytesToHexString( circuitId ).substring(4, 8) + ":" + Utils.bytesToHexString( circuitId ).substring(20, 22);
}
userName = userName.toLowerCase();
request.setStringAttribute( -1, 1, userName );
request.setStringAttribute( -1, 31, callingStation );
}
}
@Override
public void postprocessAccessRequest( RadiusPacket request, RadiusPacket response, ConnectionSet connectionSet )
throws Exception
{
response.removeAttributes( -1, 8 );
}
@Override
public void preprocessAccountingRequest( RadiusPacket request, RadiusPacket response, ConnectionSet connectionSet )
throws Exception
{
int acctStatusType = request.getIntAttribute( -1, 40, 0 );
// старты получается не обрабатываем, сессия стартует по апдейту
if( acctStatusType != 1 && acctStatusType != 101 && acctStatusType != 2)
{
preprocessAccessRequest( request, response, connectionSet );
Integer ipaddr = request.getIntAttribute( 2352, 132, null );
if( ipaddr != null )
{
request.setIntAttribute( -1, 8, ipaddr );
}
}
if ( acctStatusType == 3 ) {
// обнуляем общие счетчики трафика (нас интересуют только посервисные)
request.setIntAttribute(-1, 42, 0);
request.setIntAttribute(-1, 43, 0);
}
if ( acctStatusType == 103 || acctStatusType == 102) {
String sessionID = request.getStringAttribute(-1, 50, null);
request.setStringAttribute(-1, 44, sessionID);
}
/*if ( acctStatusType == 102) {
request.setIntAttribute(-1, 40, 2);
}*/
if ( acctStatusType == 103 || acctStatusType == 102) {
request.setIntAttribute(-1, 40, 3);
}
}
@Override
public void preprocessDhcpRequest( DhcpPacket request, DhcpPacket response )
throws Exception
{
//String userName = Utils.bytesToHexString( remoteId ).substring(4, 16) + ":" + Utils.bytesToHexString( circuitId ).substring(10, 12);
try {
byte[] circuitId = request.getSubOption( (byte)1 ).value;
byte[] remoteId = request.getSubOption( (byte)2 ).value;
if (remoteId.length == 8) {
byte[] mac = new byte[6];
byte[] port = new byte[1];
System.arraycopy(circuitId, 5, port, 0, 1);
System.arraycopy(remoteId, 2, mac, 0, 6);
request.setSubOption( (byte)1, port);
request.setSubOption( (byte)2, mac);
}
if (remoteId.length == 11) {
byte[] olt_id = new byte[8];
byte[] ont_id = new byte[1];
//21 09 01 2C 00 00 00 00 00 00 01
System.arraycopy(circuitId, 10, ont_id, 0, 1);
System.arraycopy(remoteId, 5, olt_id, 0, 6);
System.arraycopy(circuitId, 2, olt_id, 6, 2);
request.setSubOption( (byte)1, ont_id);
request.setSubOption( (byte)2, olt_id);
}
} catch (java.lang.NullPointerException e) {
return;
}
}
}
А вот почему он так сделал - только на следующей неделе узнать можно. Но вам для теста критично не должно быть, на первых порах можно remoteId зашить в код динамических классов..