Skip to content
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,17 @@ I have used this library over the last years extensively.
Please send any bug fixes to me paaguti :#at#: gmail _dot_ com

This library is released under LGPL license. Read LICENSE.txt.

Based on:
* RFC 6396
* RFC 8050

Limitations:
* RIB_IPv4_Multicast not supported
* RIB_IPv6_Multicast not supported
* RIB_GENERIC not supported
* BGP4MP_MESSAGE_LOCAL not supported
* BGP4MP_MESSAGE_LOCAL_AS4 not supported
* all previous named codes in the *_ADDPATH versions are not supported

This is great work but needs a code review / polishing and test cases.
16 changes: 3 additions & 13 deletions src/org/javamrt/mrt/Advertisement.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,12 @@
package org.javamrt.mrt;
import java.net.InetAddress;

public class Advertisement
extends Bgp4Update
public class Advertisement extends Bgp4Update
{

public
Advertisement(byte[] header,
InetAddress peerIP,
AS peerAS,
Prefix prefix,
Attributes updateAttr)
public Advertisement(byte[] header, InetAddress peerIP, AS peerAS, Prefix prefix, Attributes updateAttr)
{
super(header,
peerIP,
peerAS,
prefix,
updateAttr);
super(header, peerIP, peerAS, prefix, updateAttr);
this.updateType = 'A';
//
// this.updateStr = updateStr;
Expand Down
34 changes: 15 additions & 19 deletions src/org/javamrt/mrt/Attributes.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,25 @@
import org.javamrt.utils.RecordAccess;

public class Attributes {
private String toStr = null;
/*
* private Vector <Attribute> getAttributes () { return attributes; }
*/
private Vector<Attribute> attributes = new Vector<Attribute>(MRTConstants.ATTRIBUTE_TOTAL + 1);

public Attributes(byte[] record, int attrLen, int attrPos, int attrBytes)
public Attributes(byte[] record, int attrLen, int attrPos, int attrBytes, boolean addPath)
throws Exception {
if (attrBytes != 2 && attrBytes != 4)
throw new AttributeException(String.format(
"Attributes needs attrBytes 2 or 4 (not %d", attrBytes));
decode(record, attrLen, attrPos, attrBytes);
decode(record, attrLen, attrPos, attrBytes, addPath);
}

public Attributes(byte[] record, int attrLen, int attrPos) throws Exception {
decode(record, attrLen, attrPos, 2);
public Attributes(byte[] record, int attrLen, int attrPos, boolean addPath) throws Exception {
decode(record, attrLen, attrPos, 2, addPath);
}

private void decode(byte[] record, int attrLen, int attrPos, int attrBytes)
private void decode(byte[] record, int attrLen, int attrPos, int attrBytes, boolean addPath)
throws Exception {
byte[] buffer;

Expand All @@ -35,9 +40,7 @@ private void decode(byte[] record, int attrLen, int attrPos, int attrBytes)
Debug.printf("Attributes(...,%d,%d,%d)\n", attrLen, attrPos,
attrBytes);

attributes = new Vector<Attribute>(MRTConstants.ATTRIBUTE_TOTAL);

for (int i = 0; i < MRTConstants.ATTRIBUTE_TOTAL; i++)
for (int i = 0; i <= MRTConstants.ATTRIBUTE_TOTAL; i++)
if (i == MRTConstants.ATTRIBUTE_NEXT_HOP)
attributes.addElement(new NextHop());
else
Expand Down Expand Up @@ -161,9 +164,9 @@ private void decode(byte[] record, int attrLen, int attrPos, int attrBytes)
break;

case MRTConstants.MP_REACH:
MpReach mpReach = new MpReach(buffer);
MpReach mpReach = new MpReach(buffer, addPath);
attributes.set(MRTConstants.ATTRIBUTE_MP_REACH, mpReach);
InetAddress nhia = mpReach.getNextHop();
InetAddress nhia = mpReach.getNextHops().firstElement();
try {
NextHop nh = new NextHop(nhia);
attributes.set(MRTConstants.ATTRIBUTE_NEXT_HOP, nh);
Expand All @@ -176,7 +179,7 @@ private void decode(byte[] record, int attrLen, int attrPos, int attrBytes)
break;

case MRTConstants.MP_UNREACH:
Attribute mpUnreach = new MpUnReach(buffer);
Attribute mpUnreach = new MpUnReach(buffer, addPath);
attributes.set(MRTConstants.ATTRIBUTE_MP_UNREACH, mpUnreach);
if (Debug.compileDebug)
Debug.println("ATTRIBUTE_MP_UNREACH " + mpUnreach);
Expand Down Expand Up @@ -239,11 +242,6 @@ private void decode(byte[] record, int attrLen, int attrPos, int attrBytes)
}
}

/*
* private Vector <Attribute> getAttributes () { return attributes; }
*/
private Vector<Attribute> attributes;

public Attribute getAttribute(int index) throws Exception {
return attributes.elementAt(index);
}
Expand All @@ -254,7 +252,7 @@ public String toString() {

toStr = new String();

for (int i = MRTConstants.ATTRIBUTE_AS_PATH; i <= MRTConstants.ATTRIBUTE_AGGREGATOR; i++) {
for (int i = MRTConstants.ATTRIBUTE_AS_PATH; i <= MRTConstants.ATTRIBUTE_TOTAL; i++) {
if (attributes.elementAt(i) != null)
toStr = toStr.concat(attributes.elementAt(i).toString());
else {
Expand Down Expand Up @@ -317,6 +315,4 @@ public boolean equals(Object o) {
} // else
return false;
}

private String toStr = null;
}
97 changes: 50 additions & 47 deletions src/org/javamrt/mrt/BGPFileReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ public class BGPFileReader {
private byte[] record;

private String toString;

private long[] bgpId = null;
private org.javamrt.mrt.AS peerAS[] = null;
private java.net.InetAddress peerIP[] = null;

private int recordlen = 0;
private int type = 0;
private int subtype = 0;
private long time = 0;

private long recordCounter = 0;

/*****
*
* public BGPFileReader (BufferedInputStream in)
Expand Down Expand Up @@ -83,8 +95,7 @@ public BGPFileReader(String name) throws Exception {
}

public BGPFileReader(File f) throws IOException {
if (!f.exists())
throw new java.io.FileNotFoundException();
if (!f.exists()) throw new java.io.FileNotFoundException();
FileInputStream inStream = new FileInputStream(f);
this.toString = f.getCanonicalPath();
if (this.toString.endsWith(".gz")) {
Expand Down Expand Up @@ -117,22 +128,7 @@ public void close() throws java.io.IOException {
public String toString() {
return this.toString;
}
/***
*
* MRTRecord readNext()
*
* returns next record on successful completion null on EOF
*
* throws Exception when something goes wrong
*/

private int recordlen = 0;
private int type = 0;
private int subtype = 0;
private long time = 0;

private long recordCounter = 0;


/**
* @return the number of MRT binary format records read.<br>
* In the new MRT record formats, that has little or nothing<br>
Expand Down Expand Up @@ -163,8 +159,7 @@ public MRTRecord readNext() throws Exception {
/*
* Help GC
*/
if (record != null)
record = null;
if (record != null) record = null;
/*
* if the queue is empty, read from the file
*/
Expand Down Expand Up @@ -220,19 +215,30 @@ record = null;
case MRTConstants.PEER_INDEX_TABLE:
parsePeerIndexTable();
break;
case 2:
parseTableDumpv2(MRTConstants.AFI_IPv4);
case MRTConstants.RIB_IPV4_UNICAST:
parseTableDumpv2(MRTConstants.AFI_IPv4, false);
break;
case 4:
parseTableDumpv2(MRTConstants.AFI_IPv6);
case MRTConstants.RIB_IPV6_UNICAST:
parseTableDumpv2(MRTConstants.AFI_IPv6, false);
break;
case 6:
case MRTConstants.RIB_GENERIC:
parseGenericRib();
break;
case 3:
case 5:
case MRTConstants.RIB_IPV4_MULTICAST:
case MRTConstants.RIB_IPV6_MULTICAST:
case MRTConstants.RIB_IPV4_MULTICAST_ADDPATH:
case MRTConstants.RIB_IPV6_MULTICAST_ADDPATH:
parseTableDumpv2Multicast();
break;
case MRTConstants.RIB_IPV4_UNICAST_ADDPATH:
parseTableDumpv2(MRTConstants.AFI_IPv4, true);
break;
case MRTConstants.RIB_IPV6_UNICAST_ADDPATH:
parseTableDumpv2(MRTConstants.AFI_IPv6, true);
break;
case MRTConstants.RIB_GENERIC_AP:
parseGenericRib();
break;
default:
throw new BGPFileReaderException(
"Unknown TABLE_DUMP_V2 subtype" + subtype, header);
Expand Down Expand Up @@ -268,10 +274,13 @@ private MRTRecord parseBgp4mp(int subtype) throws Exception {
// System.out.println("parseBgp4mp("+MRTConstants.mpSubType(subtype)+")");
switch (subtype) {
case MRTConstants.BGP4MP_MESSAGE:
return parseBgp4Update((subtype == MRTConstants.BGP4MP_MESSAGE) ? 2 : 4, false);
case MRTConstants.BGP4MP_MESSAGE_AS4:
return parseBgp4Update((subtype == MRTConstants.BGP4MP_MESSAGE) ? 2
: 4);

return parseBgp4Update((subtype == MRTConstants.BGP4MP_MESSAGE_AS4) ? 4 : 2, false);
case MRTConstants.BGP4MP_MESSAGE_ADDPATH:
return parseBgp4Update((subtype == MRTConstants.BGP4MP_MESSAGE_ADDPATH) ? 2 : 4, true);
case MRTConstants.BGP4MP_MESSAGE_AS4_ADDPATH:
return parseBgp4Update((subtype == MRTConstants.BGP4MP_MESSAGE_AS4_ADDPATH) ? 4 : 2, true);
/*
* TODO
* TTOODDOO::::
Expand All @@ -282,7 +291,6 @@ private MRTRecord parseBgp4mp(int subtype) throws Exception {

case MRTConstants.BGP4MP_ENTRY:
return parseBgp4Entry(RecordAccess.getU16(record, 6));

case MRTConstants.BGP4MP_STATE_CHANGE: {
/*
* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
Expand Down Expand Up @@ -445,11 +453,7 @@ private void parsePeerIndexTable() throws Exception {
// System.exit(0);
}

private long[] bgpId = null;
private org.javamrt.mrt.AS peerAS[] = null;
private java.net.InetAddress peerIP[] = null;

private void parseTableDumpv2(int NLRItype) throws Exception {
private void parseTableDumpv2(int NLRItype, boolean addPath) throws Exception {

if (Debug.compileDebug) {
Debug.printf("parseTableDumpv2(%d)\nheader:", NLRItype);
Expand All @@ -461,7 +465,7 @@ private void parseTableDumpv2(int NLRItype) throws Exception {
int offset = 0;
long sequenceNo = RecordAccess.getU32(this.record, offset);
offset = 4;
Nlri nlri = new Nlri(this.record, offset, NLRItype);
Nlri nlri = new Nlri(this.record, offset, NLRItype, addPath);
offset += nlri.getOffset();

int entryCount = RecordAccess.getU16(this.record, offset);
Expand Down Expand Up @@ -489,7 +493,7 @@ private void parseTableDumpv2(int NLRItype) throws Exception {
offset += 4;
int attrLen = RecordAccess.getU16(this.record, offset);
offset += 2;
Attributes attributes = new Attributes(record, attrLen, offset,4);
Attributes attributes = new Attributes(record, attrLen, offset, 4, false);
offset += attrLen;


Expand All @@ -500,7 +504,7 @@ private void parseTableDumpv2(int NLRItype) throws Exception {
}
}

private MRTRecord parseBgp4Update(int asSize) throws Exception {
private MRTRecord parseBgp4Update(int asSize, boolean addPath) throws Exception {
// Bgp4Update update;

// TODO reconocer los AS de 4 bytes aquí
Expand Down Expand Up @@ -570,7 +574,7 @@ private MRTRecord parseBgp4Update(int asSize) throws Exception {
if (Debug.compileDebug) Debug.printf("int unfeasibleLen = %d\n",unfeasibleLen);

for (int i = 0; i < unfeasibleLen;) {
Nlri wNlri = new Nlri(record, offset, afi);
Nlri wNlri = new Nlri(record, offset, afi, addPath);
offset += wNlri.getOffset();
i += wNlri.getOffset();

Expand All @@ -585,7 +589,7 @@ private MRTRecord parseBgp4Update(int asSize) throws Exception {
if (attrLen > 0) {
Attributes attributes = null;
try {
attributes = new Attributes(record, attrLen, offset,asSize);
attributes = new Attributes(record, attrLen, offset, asSize, addPath);
} catch (RFC4893Exception rfce) {
//
// piggyback peer and time info
Expand Down Expand Up @@ -637,7 +641,7 @@ private MRTRecord parseBgp4Update(int asSize) throws Exception {

if (Debug.compileDebug) Debug.debug("offset(%d) record.length (%d)\n",offset,record.length);
while (offset < record.length) {
Nlri aNlri = new Nlri(record, offset, afi);
Nlri aNlri = new Nlri(record, offset, afi, addPath);
offset += aNlri.getOffset();

recordFifo.add(new Advertisement(header, srcIP, srcAs, aNlri
Expand Down Expand Up @@ -682,11 +686,10 @@ private MRTRecord parseBgp4Entry(int AFI) throws Exception {
InetAddress nextHop = InetAddress.getByAddress(RecordAccess.getBytes(
record, offset, addrSize));
offset += addrSize;
Nlri prefix = new Nlri(record, offset, AFI);
Nlri prefix = new Nlri(record, offset, AFI, false);
offset += prefix.getOffset();

Attributes attrs = new Attributes(record, record.length - offset,
offset);
Attributes attrs = new Attributes(record, record.length - offset, offset, false);
ASPath aspath = attrs.getASPath();

AS neighborAS = null;
Expand All @@ -700,12 +703,12 @@ private MRTRecord parseBgp4Entry(int AFI) throws Exception {

private void parseGenericRib() throws BGPFileReaderException{
// TODO: implement
throw new BGPFileReaderException("TODO : parseGenericRib",new byte[1]);
throw new BGPFileReaderException("TODO : parseGenericRib", new byte[1]);
}

private void parseTableDumpv2Multicast() throws BGPFileReaderException {
// TODO: implement
throw new BGPFileReaderException("TODO: parseTableDumpv2Multicast()",new byte[1]);
throw new BGPFileReaderException("TODO: parseTableDumpv2Multicast()", new byte[1]);
}

public boolean eof() {
Expand Down
7 changes: 3 additions & 4 deletions src/org/javamrt/mrt/BGPFileReaderException.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@

import org.javamrt.utils.RecordAccess;

public class BGPFileReaderException
extends java.lang.Exception
public class BGPFileReaderException extends java.lang.Exception
{
private static final long serialVersionUID = 1L;

public BGPFileReaderException(String message, byte[] header)
{
super(message + RecordAccess.arrayToString(header));
super(message); // + RecordAccess.arrayToString(header));
}
private static final long serialVersionUID = 1L;
}
4 changes: 1 addition & 3 deletions src/org/javamrt/mrt/Bgp4Update.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
import java.net.InetAddress;
import java.util.Comparator;

public class Bgp4Update
extends MRTRecord
implements Comparable<Bgp4Update>, Comparator<Bgp4Update>
public class Bgp4Update extends MRTRecord implements Comparable<Bgp4Update>, Comparator<Bgp4Update>
{
protected char updateType = '?';
protected String updateStr = "BGP4MP";
Expand Down
Loading