/**
* JRadius - A RADIUS Server Java Adapter
* Copyright (C) 2004-2005 PicoPoint, B.V.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package net.jradius.freeradius;
import java.io.IOException;
import java.nio.ByteBuffer;
import net.jradius.log.RadiusLog;
import net.jradius.packet.RadiusFormat;
import net.jradius.packet.RadiusPacket;
import net.jradius.packet.attribute.AttributeList;
import net.jradius.packet.attribute.RadiusAttribute;
import net.jradius.packet.attribute.VSAWithSubAttributes;
import net.jradius.packet.attribute.value.AttributeValue;
/**
* Packs and Unpacks Radius Packets and Attributes for the FreeRADIUS Server.
*
* @author David Bird
*/
public class FreeRadiusFormat extends RadiusFormat
{
private static final FreeRadiusFormat staticFormat = new FreeRadiusFormat();
/**
* @see net.jradius.packet.RadiusFormat#setAttributeBytes(net.jradius.packet.RadiusPacket, byte[])
public static void setAttributeBytes(RadiusPacket p, byte[] bAttributes)
{
int attributesLength = bAttributes.length;
if (attributesLength > 0)
{
staticFormat.unpackAttributes(p.getAttributes(), bAttributes, 0, attributesLength);
}
}
*/
public static void setAttributeBytes(RadiusPacket p, ByteBuffer buffer, int length)
{
staticFormat.unpackAttributes(p.getAttributes(), buffer, length, true);
}
/*
public void packAttribute(OutputStream out, RadiusAttribute a)
{
if (a instanceof VSAWithSubAttributes)
{
VSAWithSubAttributes sa = (VSAWithSubAttributes) a;
AttributeList subList = sa.getSubAttributes();
for (RadiusAttribute ra : subList.getAttributeList())
{
try
{
super.packAttribute(out, ra);
}
catch (Exception e)
{
RadiusLog.warn(e.getMessage(), e);
}
}
}
else
{
try
{
super.packAttribute(out, a);
}
catch (Exception e)
{
RadiusLog.warn(e.getMessage(), e);
}
}
}
*/
public void packAttribute(ByteBuffer buffer, RadiusAttribute a)
{
if (a instanceof VSAWithSubAttributes)
{
VSAWithSubAttributes sa = (VSAWithSubAttributes) a;
AttributeList subList = sa.getSubAttributes();
for (RadiusAttribute ra : subList.getAttributeList())
{
try
{
super.packAttribute(buffer, ra);
}
catch (Exception e)
{
RadiusLog.warn(e.getMessage(), e);
}
}
}
else
{
try
{
super.packAttribute(buffer, a);
}
catch (Exception e)
{
RadiusLog.warn(e.getMessage(), e);
}
}
}
/**
* @see net.jradius.packet.RadiusFormat#packHeader(java.io.OutputStream, net.jradius.packet.RadiusPacket, byte[], String)
public void packHeader(OutputStream out, RadiusPacket p, byte[] attributeBytes, String sharedSecret) throws IOException
{
writeUnsignedInt(out, p.getCode());
writeUnsignedInt(out, p.getIdentifier());
writeUnsignedInt(out, attributeBytes == null ? 0 : attributeBytes.length);
}
*/
public void packHeader(ByteBuffer buffer, RadiusPacket p, int attributesLength, String sharedSecret)
{
putUnsignedInt(buffer, p.getCode());
putUnsignedInt(buffer, p.getIdentifier());
putUnsignedInt(buffer, attributesLength);
}
public void packPacket(RadiusPacket packet, String sharedSecret, ByteBuffer buffer, boolean onWire) throws IOException
{
if (packet == null)
{
throw new IllegalArgumentException("Packet is null.");
}
int initialPosition = buffer.position();
buffer.position(initialPosition + 12);
packAttributeList(packet.getAttributes(), buffer, onWire);
int finalPosition = buffer.position();
int totalLength = finalPosition - initialPosition;
int attributesLength = totalLength - 12;
try
{
buffer.position(initialPosition);
packHeader(buffer, packet, attributesLength, sharedSecret);
buffer.position(finalPosition);
}
catch(Exception e)
{
RadiusLog.warn(e.getMessage(), e);
}
}
/**
* @see net.jradius.packet.RadiusFormat#packHeader(java.io.OutputStream, net.jradius.packet.attribute.RadiusAttribute)
public void packHeader(OutputStream out, RadiusAttribute a) throws IOException
{
AttributeValue attributeValue = a.getValue();
writeUnsignedInt(out, a.getFormattedType());
writeUnsignedInt(out, attributeValue.getLength());
writeUnsignedInt(out, a.getAttributeOp());
}
*/
public void packHeader(ByteBuffer buffer, RadiusAttribute a)
{
AttributeValue attributeValue = a.getValue();
putUnsignedInt(buffer, a.getFormattedType());
putUnsignedInt(buffer, attributeValue.getLength());
putUnsignedInt(buffer, a.getAttributeOp());
}
/**
* @see net.jradius.packet.RadiusFormat#unpackAttributeHeader(java.io.InputStream, net.jradius.packet.RadiusFormat.AttributeParseContext)
public int unpackAttributeHeader(InputStream in, AttributeParseContext ctx) throws IOException
{
ctx.attributeType = readUnsignedInt(in);
ctx.attributeLength = readUnsignedInt(in);
ctx.attributeOp = readUnsignedInt(in);
if (ctx.attributeType > (1 << 16))
{
// FreeRADIUS encodes the vendor number in the type
// with: if (vendor) attr->attr |= (vendor << 16);
ctx.vendorNumber = (int)((ctx.attributeType >> 16) & 0xffff);
ctx.attributeType &= 0xffff;
}
return 12;
}
*/
public void unpackAttributeHeader(ByteBuffer buffer, AttributeParseContext ctx) throws IOException
{
ctx.attributeOp = 0;
ctx.vendorNumber = -1;
ctx.padding = 0;
ctx.attributeType = getUnsignedInt(buffer);
ctx.attributeLength = getUnsignedInt(buffer) + 12;
ctx.attributeOp = getUnsignedInt(buffer);
ctx.headerLength = 12;
if (ctx.attributeType > (1 << 16))
{
// FreeRADIUS encodes the vendor number in the type
// with: if (vendor) attr->attr |= (vendor << 16);
ctx.vendorNumber = (int)((ctx.attributeType >> 16) & 0xffff);
ctx.attributeType &= 0xffff;
}
}
}