summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/attribute/AS4PathAttribute.java24
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/attribute/ASPathAttribute.java61
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/attribute/OriginAttribute.java4
3 files changed, 82 insertions, 7 deletions
diff --git a/src/main/java/com/lumaserv/bgp/protocol/attribute/AS4PathAttribute.java b/src/main/java/com/lumaserv/bgp/protocol/attribute/AS4PathAttribute.java
index 796fbea..cd52173 100644
--- a/src/main/java/com/lumaserv/bgp/protocol/attribute/AS4PathAttribute.java
+++ b/src/main/java/com/lumaserv/bgp/protocol/attribute/AS4PathAttribute.java
@@ -1,5 +1,6 @@
package com.lumaserv.bgp.protocol.attribute;
+import lombok.NoArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@@ -7,6 +8,7 @@ import java.util.ArrayList;
import java.util.List;
@Getter
+@NoArgsConstructor
@Setter
public class AS4PathAttribute implements PathAttribute {
@@ -34,7 +36,27 @@ public class AS4PathAttribute implements PathAttribute {
}
public byte[] build() {
- return new byte[0];
+ byte length = 0;
+ for (Segment seg: segments) {
+ length += 2 + seg.asns.size() * 4;
+ }
+ int offset = 0;
+ byte[] data = new byte[length];
+
+ for (Segment seg: segments) {
+ data[offset] = seg.type;
+ data[offset + 1] = (byte)seg.asns.size();
+ for (int i=0; i<seg.asns.size(); i++) {
+ int asn = seg.asns.get(i);
+ data[offset + 2 + (i * 4)] = (byte)((asn >> 24) & 0xFF);
+ data[offset + 3 + (i * 4)] = (byte)((asn >> 16) & 0xFF);
+ data[offset + 4 + (i * 4)] = (byte)((asn >> 8) & 0xFF);
+ data[offset + 5 + (i * 4)] = (byte)(asn & 0xFF);
+ }
+ offset += 2 + seg.asns.size() * 4;
+ }
+
+ return data;
}
@Getter
diff --git a/src/main/java/com/lumaserv/bgp/protocol/attribute/ASPathAttribute.java b/src/main/java/com/lumaserv/bgp/protocol/attribute/ASPathAttribute.java
index ed95b2a..44deb8f 100644
--- a/src/main/java/com/lumaserv/bgp/protocol/attribute/ASPathAttribute.java
+++ b/src/main/java/com/lumaserv/bgp/protocol/attribute/ASPathAttribute.java
@@ -7,21 +7,26 @@ import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
+import java.util.EnumSet;
import java.util.List;
@Getter
-@NoArgsConstructor
@Setter
public class ASPathAttribute implements PathAttribute {
+ final private boolean isAS4;
List<Segment> segments = new ArrayList<>();
+ public ASPathAttribute(BGPSession session) {
+ isAS4 = session.isAS4Capability();
+ }
+
public ASPathAttribute(BGPSession session, byte typeCode, byte[] data) {
- final boolean isAS4 = session.isAS4Capability();
+ this(session);
final int asnLen = isAS4 ? 4 : 2;
int offset = 0;
while (offset < data.length) {
- Segment segment = new Segment().setType(data[offset]);
+ Segment segment = new Segment().setType(Segment.Type.fromByte(data[offset]));
byte length = data[offset + 1];
for(int i=0; i<length; i++) {
int asn;
@@ -46,13 +51,59 @@ public class ASPathAttribute implements PathAttribute {
}
public byte[] build() {
- return new byte[0];
+ final int asnLen = isAS4 ? 4 : 2;
+ byte length = 0;
+ for (Segment seg: segments) {
+ length += 2 + seg.asns.size() * asnLen;
+ }
+ int offset = 0;
+ byte[] data = new byte[length];
+
+ for (Segment seg: segments) {
+ data[offset] = seg.type.code;
+ data[offset + 1] = (byte)seg.asns.size();
+ for (int i=0; i<seg.asns.size(); i++) {
+ int asn = seg.asns.get(i);
+ if (isAS4) {
+ data[offset + 2 + (i * 4)] = (byte)((asn >> 24) & 0xFF);
+ data[offset + 3 + (i * 4)] = (byte)((asn >> 16) & 0xFF);
+ data[offset + 4 + (i * 4)] = (byte)((asn >> 8) & 0xFF);
+ data[offset + 5 + (i * 4)] = (byte)(asn & 0xFF);
+ } else {
+ data[offset + 2 + (i * 2)] = (byte)((asn >> 8) & 0xFF);
+ data[offset + 3 + (i * 2)] = (byte)(asn & 0xFF);
+ }
+ }
+ offset += 2 + seg.asns.size() * asnLen;
+ }
+
+ return data;
}
@Getter
@Setter
public static class Segment {
- byte type;
+ @Getter
+ public enum Type {
+ SET(1),
+ SEQUENCE(2);
+
+ byte code;
+
+ Type(int code) {
+ this.code = (byte)code;
+ }
+
+ public static Type fromByte(byte code) {
+ return EnumSet.allOf(Type.class)
+ .stream()
+ .filter(e -> e.getCode() == code)
+ .findAny()
+ .orElseThrow(() -> new IllegalArgumentException("unknown path segment type: " + code));
+ }
+ }
+
+ Type type;
List<Integer> asns = new ArrayList<>();
public String toString() {
diff --git a/src/main/java/com/lumaserv/bgp/protocol/attribute/OriginAttribute.java b/src/main/java/com/lumaserv/bgp/protocol/attribute/OriginAttribute.java
index dcb17fb..575b848 100644
--- a/src/main/java/com/lumaserv/bgp/protocol/attribute/OriginAttribute.java
+++ b/src/main/java/com/lumaserv/bgp/protocol/attribute/OriginAttribute.java
@@ -43,7 +43,9 @@ public class OriginAttribute implements PathAttribute {
}
public byte[] build() {
- return new byte[0];
+ byte[] data = new byte[1];
+ data[0] = origin.code;
+ return data;
}
public String toString() {