diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2023-03-06 22:25:55 +0100 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2023-11-11 23:59:40 +0100 |
commit | 775790de50a74bbaca50bee837b3e41501699cb1 (patch) | |
tree | 369ec21d563d303f85af9f46931e06027dcbd947 | |
parent | 028ff0be508bf65cd7f811e645384c34ae8983b4 (diff) |
Implement build() for a few attributes
Implement build() for AS4PathAttribute, ASPathAttribute
and OriginAttribute.
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() { |