summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/AFI.java21
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java2
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/SAFI.java21
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/attribute/MPReachableNLRIAttribute.java59
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java36
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/attribute/PathAttribute.java4
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/message/BGPOpen.java19
7 files changed, 160 insertions, 2 deletions
diff --git a/src/main/java/com/lumaserv/bgp/protocol/AFI.java b/src/main/java/com/lumaserv/bgp/protocol/AFI.java
new file mode 100644
index 0000000..1dce43b
--- /dev/null
+++ b/src/main/java/com/lumaserv/bgp/protocol/AFI.java
@@ -0,0 +1,21 @@
+package com.lumaserv.bgp.protocol;
+
+import java.util.EnumSet;
+
+import lombok.Getter;
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+@Getter
+public enum AFI {
+ IPV4(1, "IPv4"),
+ IPV6(2, "IPv6");
+
+ int value;
+ String desc;
+
+ public static AFI fromInteger(int value) {
+ return EnumSet.allOf(AFI.class).stream().filter(e -> e.getValue() == value).findAny().orElseThrow(
+ () -> new IllegalArgumentException("unknown address family: " + value));
+ }
+}
diff --git a/src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java b/src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java
index be70c4f..f68677c 100644
--- a/src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java
+++ b/src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java
@@ -13,7 +13,7 @@ import java.net.UnknownHostException;
public class IPPrefix {
byte[] address;
- byte length;
+ int length;
public String toString() {
try {
diff --git a/src/main/java/com/lumaserv/bgp/protocol/SAFI.java b/src/main/java/com/lumaserv/bgp/protocol/SAFI.java
new file mode 100644
index 0000000..5fa6b99
--- /dev/null
+++ b/src/main/java/com/lumaserv/bgp/protocol/SAFI.java
@@ -0,0 +1,21 @@
+package com.lumaserv.bgp.protocol;
+
+import java.util.EnumSet;
+
+import lombok.Getter;
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+@Getter
+public enum SAFI {
+ UNICAST(1, "NLRI Unicast"),
+ MULTICAST(2, "NLRI Multicast");
+
+ int value;
+ String desc;
+
+ public static SAFI fromInteger(int value) {
+ return EnumSet.allOf(SAFI.class).stream().filter(e -> e.getValue() == value).findAny().orElseThrow(
+ () -> new IllegalArgumentException("unknown subsequent address family: " + value));
+ }
+}
diff --git a/src/main/java/com/lumaserv/bgp/protocol/attribute/MPReachableNLRIAttribute.java b/src/main/java/com/lumaserv/bgp/protocol/attribute/MPReachableNLRIAttribute.java
new file mode 100644
index 0000000..346cb0e
--- /dev/null
+++ b/src/main/java/com/lumaserv/bgp/protocol/attribute/MPReachableNLRIAttribute.java
@@ -0,0 +1,59 @@
+package com.lumaserv.bgp.protocol.attribute;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.lumaserv.bgp.protocol.AFI;
+import com.lumaserv.bgp.protocol.IPPrefix;
+import com.lumaserv.bgp.protocol.SAFI;
+
+@Getter
+@Setter
+public class MPReachableNLRIAttribute implements PathAttribute {
+
+ AFI afi;
+ SAFI safi;
+ byte[] nextHop;
+ Collection<IPPrefix> nlriPrefixes;
+
+ public MPReachableNLRIAttribute(byte typeCode, byte[] data) {
+ afi = AFI.fromInteger((data[0] << 8) | data[1]);
+ safi = SAFI.fromInteger(data[2]);
+ int nhLen = data[3];
+ nextHop = new byte[nhLen];
+ System.arraycopy(data, 4, nextHop, 0, nextHop.length);
+ int nlriLen = data.length - 5 - nhLen;
+ nlriPrefixes = new ArrayList<>();
+
+ int offset = 4 + nhLen + 1;
+ int offsetOffset = offset;
+ while ((offset - offsetOffset) < nlriLen) {
+ IPPrefix prefix = new IPPrefix()
+ .setLength((int)(data[offset]&0xff)) // FIXME IPv4/IPv6 etc
+ .setAddress(new byte[16]);
+ offset++;
+ int addressLen = (int) Math.ceil(prefix.getLength() / 8d);
+ System.arraycopy(data, offset, prefix.getAddress(), 0, addressLen);
+ offset += addressLen;
+ nlriPrefixes.add(prefix);
+ }
+ }
+
+ public byte getTypeCode() {
+ return 14;
+ }
+
+ public void build(ByteBuffer b) {
+ // FIXME
+ }
+
+ public String toString() {
+ return "AFI:" + afi + " SAFI:" + safi + " NLRIs:" + nlriPrefixes;
+ }
+}
diff --git a/src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java b/src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java
new file mode 100644
index 0000000..43dc8d5
--- /dev/null
+++ b/src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java
@@ -0,0 +1,36 @@
+package com.lumaserv.bgp.protocol.attribute;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.lumaserv.bgp.protocol.AFI;
+import com.lumaserv.bgp.protocol.SAFI;
+
+import java.nio.ByteBuffer;
+
+@Getter
+@Setter
+public class MPUnreachableNLRIAttribute implements PathAttribute {
+
+ AFI afi;
+ SAFI safi;
+ int nlriLen;
+
+ public MPUnreachableNLRIAttribute(byte typeCode, byte[] data) {
+ afi = AFI.fromInteger((data[0] << 8) | data[1]);
+ safi = SAFI.fromInteger(data[2]);
+ nlriLen = data.length - 3;
+ }
+
+ public byte getTypeCode() {
+ return 15;
+ }
+
+ public void build(ByteBuffer b) {
+ // FIXME
+ }
+
+ public String toString() {
+ return "AFI:" + afi + " SAFI:" + safi + " NLRIs:" + nlriLen;
+ }
+}
diff --git a/src/main/java/com/lumaserv/bgp/protocol/attribute/PathAttribute.java b/src/main/java/com/lumaserv/bgp/protocol/attribute/PathAttribute.java
index 95156ed..117a147 100644
--- a/src/main/java/com/lumaserv/bgp/protocol/attribute/PathAttribute.java
+++ b/src/main/java/com/lumaserv/bgp/protocol/attribute/PathAttribute.java
@@ -21,6 +21,10 @@ public interface PathAttribute {
return new AggregatorAttribute(typeCode, data);
case 8:
return new CommunitiesAttribute(typeCode, data);
+ case 14:
+ return new MPReachableNLRIAttribute(typeCode, data);
+ case 15:
+ return new MPUnreachableNLRIAttribute(typeCode, data);
case 16:
return new ExtendedCommuntiesAttribute(typeCode, data);
case 17:
diff --git a/src/main/java/com/lumaserv/bgp/protocol/message/BGPOpen.java b/src/main/java/com/lumaserv/bgp/protocol/message/BGPOpen.java
index 875f7bc..e83b751 100644
--- a/src/main/java/com/lumaserv/bgp/protocol/message/BGPOpen.java
+++ b/src/main/java/com/lumaserv/bgp/protocol/message/BGPOpen.java
@@ -22,13 +22,30 @@ public class BGPOpen {
}
public byte[] build() {
- byte[] message = new byte[6 + identifier.length];
+ byte[] message = new byte[5 + identifier.length + 1 + 2 + 2 * 6];
message[0] = version;
message[1] = (byte) (asn >> 8);
message[2] = (byte) (asn & 0xFF);
message[3] = (byte) (holdTime >> 8);
message[4] = (byte) (holdTime & 0xFF);
System.arraycopy(identifier, 0, message, 5, identifier.length);
+ message[5 + identifier.length + 0] = 14; // Length (0E)
+ message[5 + identifier.length + 1] = 2; // Parameter Type: capability (02)
+ message[5 + identifier.length + 2] = 12; // Length (0C)
+
+ message[5 + identifier.length + 3] = 1; // Type: multiprotocol (01)
+ message[5 + identifier.length + 4] = 4; // Length (04)
+ message[5 + identifier.length + 5] = 0; // IPv6 (0002)
+ message[5 + identifier.length + 6] = 2; //
+ message[5 + identifier.length + 7] = 0; // Reserved
+ message[5 + identifier.length + 8] = 1; // Unicast (01)
+
+ message[5 + identifier.length + 9] = 1; // Type: multiprotocol (01)
+ message[5 + identifier.length +10] = 4; // Length (04)
+ message[5 + identifier.length +11] = 0; // IPv4 (0001)
+ message[5 + identifier.length +12] = 1; //
+ message[5 + identifier.length +13] = 0; // Reserved
+ message[5 + identifier.length +14] = 1; // Unicast (01)
return message;
}