d54c141d2ed4136df41939672b47d6ebf870c08d
[bgpcep.git] / bgp / util / src / main / java / org / opendaylight / protocol / bgp / util / BinaryBGPDumpFileParser.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.protocol.bgp.util;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.primitives.UnsignedBytes;
12 import java.util.Arrays;
13 import java.util.LinkedList;
14 import java.util.List;
15 import org.opendaylight.protocol.util.ByteArray;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 /**
20  * This extracter extracts BGP messages in binary form from a file in MRT format.
21  * (http://www.ripe.net/data-tools/stats/ris/ris-raw-data) The parser detects BGP messages by searching for 16 FF bytes,
22  * everything else before or after is ignored.
23  */
24 public final class BinaryBGPDumpFileParser {
25     private static final Logger LOG = LoggerFactory.getLogger(BinaryBGPDumpFileParser.class);
26     private static final int MINIMAL_LENGTH = 19;
27     private static final int MARKER_LENGTH = 16;
28
29     private BinaryBGPDumpFileParser() {
30         throw new UnsupportedOperationException();
31     }
32
33     /**
34      * Extract BGP messages from binary file in MRT format.
35      *
36      * @param byteArray array of bytes with BGP messages in binary form.
37      * @return list with byte arrays representing extracted messages.
38      */
39     public static List<byte[]> parseMessages(final byte[] byteArray) {
40
41         final List<byte[]> messages = new LinkedList();
42         // search for 16 FFs
43         for (int i = 0; i < byteArray.length; i++) {
44             final byte b = byteArray[i];
45
46             // Marker start
47             if (b == UnsignedBytes.MAX_VALUE) {
48                 final int start = i;
49                 int ffCount = 0;
50                 for (int j = i; j <= i + MARKER_LENGTH; j++) {
51                     // Check marker
52                     if (byteArray[j] == UnsignedBytes.MAX_VALUE) {
53                         ffCount++;
54                     } else if (ffCount == MARKER_LENGTH) {
55                         if (j == i + MARKER_LENGTH) {
56                             // Parse length
57                             final int length = ByteArray.bytesToInt(new byte[]{ byteArray[j], byteArray[j + 1] });
58
59                             Preconditions.checkArgument(length >= MINIMAL_LENGTH,
60                                     "Invalid message at index " + start
61                                     + ", length atribute is lower than " + MINIMAL_LENGTH);
62
63                             final byte[] message = Arrays.copyOfRange(byteArray, start, start + length);
64                             messages.add(message);
65                             j += length - MARKER_LENGTH;
66                         }
67                         i = j;
68                         break;
69                     } else {
70                         break;
71                     }
72                 }
73             }
74
75         }
76         LOG.info("Succesfully extracted {} messages", messages.size());
77         return messages;
78     }
79 }