2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.util;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.annotations.VisibleForTesting;
13 import com.google.common.base.Preconditions;
14 import com.google.common.base.Strings;
15 import com.google.common.collect.Lists;
16 import com.google.common.io.BaseEncoding;
17 import com.google.common.io.CharStreams;
19 import java.io.FileInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.util.List;
24 import javax.annotation.concurrent.Immutable;
25 import org.opendaylight.protocol.util.ByteArray;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * Read text file, parse BGP messages. File can contain comments or other data. BGP messages are detected using 16 ff
31 * marker. New lines and spaces are ignored.
34 public final class HexDumpBGPFileParser {
35 private static final int MINIMAL_LENGTH = 19;
36 private static final Logger LOG = LoggerFactory.getLogger(HexDumpBGPFileParser.class);
37 private static final String FF_16 = Strings.repeat("FF", 16);
39 private HexDumpBGPFileParser() {
40 throw new UnsupportedOperationException();
43 public static List<byte[]> parseMessages(final File file) throws IOException {
44 Preconditions.checkArgument(file != null, "Filename cannot be null");
45 return parseMessages(new FileInputStream(file));
48 public static List<byte[]> parseMessages(final InputStream is) throws IOException {
50 try (InputStreamReader isr = new InputStreamReader(is, "UTF-8")) {
51 return parseMessages(CharStreams.toString(isr));
57 public static List<byte[]> parseMessages(final String c) {
58 final String content = clearWhiteSpaceToUpper(c);
59 final int sixteen = 16;
63 final List<byte[]> messages = Lists.newLinkedList();
64 int idx = content.indexOf(FF_16, 0);
66 // next 2 bytes are length
67 final int lengthIdx = idx + sixteen * 2;
68 final int messageIdx = lengthIdx + four;
69 final String hexLength = content.substring(lengthIdx, messageIdx);
70 final byte[] byteLength = BaseEncoding.base16().decode(hexLength);
71 final int length = ByteArray.bytesToInt(byteLength);
72 final int messageEndIdx = idx + length * 2;
74 // Assert that message is longer than minimum 19(header.length == 19)
75 // If length in BGP message would be 0, loop would never end
76 Preconditions.checkArgument(length >= MINIMAL_LENGTH, "Invalid message at index " + idx + ", length atribute is lower than "
79 final String hexMessage = content.substring(idx, messageEndIdx);
80 final byte[] message = BaseEncoding.base16().decode(hexMessage);
81 messages.add(message);
83 idx = content.indexOf(FF_16, idx);
85 LOG.info("Succesfully extracted {} messages", messages.size());
90 static String clearWhiteSpaceToUpper(final String line) {
91 return line.replaceAll("\\s", "").toUpperCase();