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;
11 import java.io.FileInputStream;
12 import java.io.FileNotFoundException;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.InputStreamReader;
16 import java.util.List;
18 import javax.annotation.concurrent.Immutable;
20 import org.apache.commons.codec.DecoderException;
21 import org.apache.commons.codec.binary.Hex;
22 import org.opendaylight.protocol.util.ByteArray;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
26 import com.google.common.annotations.VisibleForTesting;
27 import com.google.common.base.Preconditions;
28 import com.google.common.base.Strings;
29 import com.google.common.collect.Lists;
30 import com.google.common.io.CharStreams;
33 * Read text file, parse BGP messages. File can contain comments or other data. BGP messages are detected using 16 ff marker.
34 * New lines and spaces are ignored. Use {@link ByteArray#bytesToHexString(byte[])} for serializing bytes to this format.
37 public class HexDumpBGPFileParser {
38 private static final int MINIMAL_LENGTH = 19;
39 private static final Logger LOG = LoggerFactory.getLogger(HexDumpBGPFileParser.class);
40 private static final String ff_16 = Strings.repeat("FF", 16);
42 public static List<byte[]> parseMessages(final File file) throws FileNotFoundException, IOException {
43 Preconditions.checkArgument(file != null, "Filename cannot be null");
44 return parseMessages(new FileInputStream(file));
47 public static List<byte[]> parseMessages(final InputStream is) throws IOException {
48 Preconditions.checkNotNull(is);
49 try (InputStreamReader isr = new InputStreamReader(is)) {
50 return parseMessages(CharStreams.toString(isr));
56 public static List<byte[]> parseMessages(String content) {
57 content = clearWhiteSpace_toUpper(content);
60 List<byte[]> messages = Lists.newLinkedList();
62 while ((idx = content.indexOf(ff_16, idx)) > -1) {
63 // next 2 bytes are length
64 int lengthIdx = idx + 16 * 2;
65 int messageIdx = lengthIdx + 4;
66 String hexLength = content.substring(lengthIdx, messageIdx);
67 byte[] byteLength = null;
69 byteLength = Hex.decodeHex(hexLength.toCharArray());
70 } catch (DecoderException e) {
71 throw new RuntimeException(e);
73 int length = ByteArray.bytesToInt(byteLength);
74 int messageEndIdx = idx + length * 2;
76 // Assert that message is longer than minimum 19(header.length == 19)
77 // If length in BGP message would be 0, loop would never end
78 Preconditions.checkArgument(length >= MINIMAL_LENGTH,
79 "Invalid message at index " + idx
80 + ", length atribute is lower than " + MINIMAL_LENGTH);
82 String hexMessage = content.substring(idx, messageEndIdx);
83 byte[] message = null;
85 message = Hex.decodeHex(hexMessage.toCharArray());
86 } catch (DecoderException e) {
87 new RuntimeException(e);
89 messages.add(message);
92 LOG.info("Succesfully extracted " + messages.size() + " messages");
97 static String clearWhiteSpace_toUpper(final String line){
98 return line.replaceAll("\\s", "").toUpperCase();