summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/pim/PIMHello.java
blob: 9ad3fdbde706e3545d5885f573edce288e308abc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onlab.packet.pim;

import org.onlab.packet.BasePacket;
import org.onlab.packet.Deserializer;
import org.onlab.packet.IPacket;
import org.onlab.packet.IpAddress;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

import static org.onlab.packet.PacketUtils.checkInput;

public class PIMHello extends BasePacket {

    private IpAddress nbrIpAddress;
    private boolean priorityPresent = false;

    private Map<Short, PIMHelloOption> options = new HashMap<>();

    /**
     * Create a PIM Hello packet with the most common hello options and default
     * values.  The values of any options can be easily changed by modifying the value of
     * the option with the desired change.
     */
    public void createDefaultOptions() {
        options.put(PIMHelloOption.OPT_HOLDTIME, new PIMHelloOption(PIMHelloOption.OPT_HOLDTIME));
        options.put(PIMHelloOption.OPT_PRIORITY, new PIMHelloOption(PIMHelloOption.OPT_PRIORITY));
        options.put(PIMHelloOption.OPT_GENID, new PIMHelloOption(PIMHelloOption.OPT_GENID));
    }

    /**
     * Add a PIM Hello option to this hello message.  Note
     *
     * @param opt the PIM Hello option we are adding
     */
    public void addOption(PIMHelloOption opt) {
        this.options.put(opt.getOptType(), opt);
    }

    public Map<Short, PIMHelloOption> getOptions() {
        return this.options;
    }

    /**
     * Sets all payloads parent packet if applicable, then serializes this
     * packet and all payloads.
     *
     * @return a byte[] containing this packet and payloads
     */
    @Override
    public byte[] serialize() {
        int totalLen = 0;


         // Since we are likely to only have 3-4 options, go head and walk the
         // hashmap twice, once to calculate the space needed to allocate a
         // buffer, the second time serialize the options into the buffer.  This
         // saves us from allocating an over sized buffer the re-allocating and
         // copying.
        for (Short optType : options.keySet()) {
            PIMHelloOption opt = options.get(optType);
            totalLen += PIMHelloOption.MINIMUM_OPTION_LEN_BYTES + opt.getOptLength();
        }

        byte[] data = new byte[totalLen];
        ByteBuffer bb = ByteBuffer.wrap(data);

        // Now serialize the data.
        for (Short optType : options.keySet()) {
            PIMHelloOption opt = options.get(optType);
            bb.put(opt.serialize());
        }
        return data;
    }

    /**
     * XXX: This is deprecated, DO NOT USE, use the deserializer() function instead.
     */
    public IPacket deserialize(final byte[] data, final int offset,
                               final int length) {
        // TODO: throw an expection?
        return null;
    }

    /**
     * Deserialize this hello message.
     *
     * @return a deserialized hello message
     */
    public static Deserializer<PIMHello> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, PIMHelloOption.MINIMUM_OPTION_LEN_BYTES);
            final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);

            PIMHello hello = new PIMHello();
            while (bb.hasRemaining()) {
                PIMHelloOption opt = PIMHelloOption.deserialize(bb);
                hello.addOption(opt);
            }
            return hello;
        };
    }
}