diff --git a/CHANGES b/CHANGES
index 17867751..f76a14d5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
TinyRadius Change Log
+1.1.2:
+Support of 2 byte attribute tag length
+
Plans for 1.0: Asynchronous Radius client (see TODO)
0.9.9:
diff --git a/pom.xml b/pom.xml
index 302f9b86..ffc34c45 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
org.tinyradius
tinyradius
- 1.1.1-SNAPSHOT
+ 1.1.2-SNAPSHOT
jar
TinyRadius Java Radius Library
diff --git a/src/main/java/org/tinyradius/attribute/RadiusAttribute.java b/src/main/java/org/tinyradius/attribute/RadiusAttribute.java
index 2059b79a..e5108802 100644
--- a/src/main/java/org/tinyradius/attribute/RadiusAttribute.java
+++ b/src/main/java/org/tinyradius/attribute/RadiusAttribute.java
@@ -77,8 +77,9 @@ public int getAttributeType() {
* type code, 0-255
*/
public void setAttributeType(int attributeType) {
- if (attributeType < 0 || attributeType > 255)
- throw new IllegalArgumentException("attribute type invalid: " + attributeType);
+ // Vendor specific attribute has values > 255 and < 1
+ /*if (attributeType < 0 || attributeType > 255)
+ throw new IllegalArgumentException("attribute type invalid: " + attributeType);*/
this.attributeType = attributeType;
}
@@ -165,6 +166,28 @@ public byte[] writeAttribute() {
return attr;
}
+ /**
+ * Returns this attribute encoded as a byte array.
+ *
+ * @return attribute
+ */
+ public byte[] write2ByteAttribute() {
+ if (getAttributeType() == -1)
+ throw new IllegalArgumentException("attribute type not set");
+ if (attributeData == null)
+ throw new NullPointerException("attribute data not set");
+
+ byte[] attr = new byte[4 + attributeData.length];
+ attr[0] = (byte) (getAttributeType() >> 8 & 0x0ff);
+ attr[1] = (byte) (getAttributeType() & 0x0ff);
+ int data_length = 2 + attributeData.length;
+ attr[2] = (byte) (data_length >> 8 & 0x0ff);
+ attr[3] = (byte) (data_length & 0x0ff);
+ System.arraycopy(attributeData, 0, attr, 4, attributeData.length);
+ return attr;
+ }
+
+
/**
* Reads in this attribute from the passed byte array.
*
@@ -181,6 +204,28 @@ public void readAttribute(byte[] data, int offset, int length) throws RadiusExce
setAttributeData(attrData);
}
+ /**
+ * Reads in this attribute from the passed byte array.
+ *
+ * @param data
+ */
+ public void read2ByteAttribute(byte[] data, int offset, int length) throws RadiusException {
+ if (length < 2)
+ throw new RadiusException("attribute length too small: " + length);
+ int attrType = (usByteToInt(data[offset]) << 8 | usByteToInt(data[offset + 1]));
+ int attrLen = (usByteToInt(data[offset + 2]) << 8 | usByteToInt(data[offset + 3]));
+ byte[] attrData = new byte[attrLen - 4];
+ System.arraycopy(data, offset + 4, attrData, 0, attrLen - 4);
+ setAttributeType(attrType);
+ setAttributeData(attrData);
+ }
+
+ private static int usByteToInt(byte b) {
+ return b & 0xFF;
+ }
+
+
+
/**
* String representation for debugging purposes.
*
diff --git a/src/main/java/org/tinyradius/attribute/VendorSpecificAttribute.java b/src/main/java/org/tinyradius/attribute/VendorSpecificAttribute.java
index 5adf0767..e9cfed81 100644
--- a/src/main/java/org/tinyradius/attribute/VendorSpecificAttribute.java
+++ b/src/main/java/org/tinyradius/attribute/VendorSpecificAttribute.java
@@ -149,8 +149,10 @@ public List getSubAttributes() {
* @return list of RadiusAttribute objects, does not return null
*/
public List getSubAttributes(int attributeType) {
+ // Vendor specific attribute has values > 255 and < 1
+ /*
if (attributeType < 1 || attributeType > 255)
- throw new IllegalArgumentException("sub-attribute type out of bounds");
+ throw new IllegalArgumentException("sub-attribute type out of bounds");*/
LinkedList result = new LinkedList();
for (Iterator i = subAttributes.iterator(); i.hasNext();) {
@@ -243,7 +245,10 @@ public byte[] writeAttribute() {
try {
for (Iterator i = subAttributes.iterator(); i.hasNext();) {
RadiusAttribute a = (RadiusAttribute) i.next();
- bos.write(a.writeAttribute());
+ if(getChildVendorId() == 8164)
+ bos.write(a.write2ByteAttribute());
+ else
+ bos.write(a.writeAttribute());
}
}
catch (IOException ioe) {
@@ -296,22 +301,43 @@ public void readAttribute(byte[] data, int offset, int length) throws RadiusExce
int count = 0;
while (pos < vsaLen) {
if (pos + 1 >= vsaLen)
- throw new RadiusException("Vendor-Specific attribute malformed");
+ throw new RadiusException("Vendor-Specific attribute malformed [pos +1 >= vsaLen]");
// int vsaSubType = data[(offset + 6) + pos] & 0x0ff;
- int vsaSubLen = data[(offset + 6) + pos + 1] & 0x0ff;
+ int vsaSubLen = 0;
+ if(vendorId ==8164) //Starent NW 2 byte tag & length
+ {
+ vsaSubLen = (unsignedByteToInt(data[(offset + 6) + pos + 2]) << 8 | unsignedByteToInt(data[(offset + 6) + pos + 3]));
+ }
+ else
+ vsaSubLen = data[(offset + 6) + pos + 1] & 0x0ff;
+ if(vsaSubLen < 2)
+ throw new RadiusException("Vendor-Specific attribute malformed: attr length: " + vsaSubLen);
pos += vsaSubLen;
count++;
}
if (pos != vsaLen)
- throw new RadiusException("Vendor-Specific attribute malformed");
+ throw new RadiusException("Vendor-Specific attribute malformed [pos != vsaLen]");
subAttributes = new ArrayList(count);
pos = 0;
while (pos < vsaLen) {
- int subtype = data[(offset + 6) + pos] & 0x0ff;
- int sublength = data[(offset + 6) + pos + 1] & 0x0ff;
+ int subtype = 0;
+ int sublength = 0;
+ if(vendorId ==8164) //Starent NW 2 byte tag & length
+ {
+ subtype = (unsignedByteToInt(data[(offset + 6) + pos]) << 8 | unsignedByteToInt(data[(offset + 6) + pos + 1]));
+ sublength = (unsignedByteToInt(data[(offset + 6) + pos + 2]) << 8 | unsignedByteToInt(data[(offset + 6) + pos + 3]));
+ }
+ else
+ {
+ subtype = data[(offset + 6) + pos] & 0x0ff;
+ sublength = data[(offset + 6) + pos + 1] & 0x0ff;
+ }
RadiusAttribute a = createRadiusAttribute(getDictionary(), vendorId, subtype);
- a.readAttribute(data, (offset + 6) + pos, sublength);
+ if(vendorId ==8164) //Starent NW 2 byte tag & length
+ a.read2ByteAttribute(data, (offset + 6) + pos, sublength);
+ else
+ a.readAttribute(data, (offset + 6) + pos, sublength);
subAttributes.add(a);
pos += sublength;
}
diff --git a/src/main/java/org/tinyradius/dictionary/AttributeType.java b/src/main/java/org/tinyradius/dictionary/AttributeType.java
index 5b62600e..cc549736 100644
--- a/src/main/java/org/tinyradius/dictionary/AttributeType.java
+++ b/src/main/java/org/tinyradius/dictionary/AttributeType.java
@@ -1,5 +1,10 @@
/**
* $Id: AttributeType.java,v 1.3 2005/09/06 18:06:33 wuttke Exp $
+ * Copyright by teuto.net Netzdienste GmbH 2005. All rights reserved.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation. Commercial licenses also available.
+ * See the accompanying file LICENSE for details.
*
* @author Matthias Wuttke
* @version $Revision: 1.3 $
@@ -68,8 +73,9 @@ public int getTypeCode() {
* type code, 1-255
*/
public void setTypeCode(int code) {
- if (code < 1 || code > 255)
- throw new IllegalArgumentException("code out of bounds");
+ // Vendor specific attribute has values > 255 and < 1
+ /*if (code < 1 || code > 255)
+ throw new IllegalArgumentException("code out of bounds");*/
this.typeCode = code;
}
diff --git a/src/main/java/org/tinyradius/packet/RadiusPacket.java b/src/main/java/org/tinyradius/packet/RadiusPacket.java
index e8f34af1..6d6135cf 100644
--- a/src/main/java/org/tinyradius/packet/RadiusPacket.java
+++ b/src/main/java/org/tinyradius/packet/RadiusPacket.java
@@ -215,8 +215,10 @@ public String getPacketTypeName() {
* packet type, 0-255
*/
public void setPacketType(int type) {
+ // Vendor specific attribute has values > 255 and < 1
+ /*
if (type < 1 || type > 255)
- throw new IllegalArgumentException("packet type out of bounds");
+ throw new IllegalArgumentException("packet type out of bounds");*/
this.packetType = type;
}
@@ -325,8 +327,10 @@ public void removeAttribute(RadiusAttribute attribute) {
* attribute type to remove
*/
public void removeAttributes(int type) {
+ // Vendor specific attribute has values > 255 and < 1
+ /*
if (type < 1 || type > 255)
- throw new IllegalArgumentException("attribute type out of bounds");
+ throw new IllegalArgumentException("attribute type out of bounds");*/
Iterator i = attributes.iterator();
while (i.hasNext()) {
@@ -393,8 +397,10 @@ public void removeAttributes(int vendorId, int typeCode) {
* @return list of RadiusAttribute objects, does not return null
*/
public List getAttributes(int attributeType) {
+ // Vendor specific attribute has values > 255 and < 1
+ /*
if (attributeType < 1 || attributeType > 255)
- throw new IllegalArgumentException("attribute type out of bounds");
+ throw new IllegalArgumentException("attribute type out of bounds");*/
LinkedList result = new LinkedList();
for (Iterator i = attributes.iterator(); i.hasNext();) {