blob: 0b918d4a874cba74b5f0528aca4815588b193e8a [file] [log] [blame]
Thomas Vachuska58de4162015-09-10 16:15:33 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
sanghob35a6192015-04-01 13:05:26 -070016package org.onlab.packet;
17
18import java.nio.ByteBuffer;
19import java.util.HashMap;
20import java.util.Map;
21
Jian Li5fc14292015-12-04 11:30:46 -080022import static com.google.common.base.MoreObjects.toStringHelper;
Jonathan Hart2a655752015-04-07 16:46:33 -070023import static org.onlab.packet.PacketUtils.checkInput;
24
Jian Li5fc14292015-12-04 11:30:46 -080025/**
26 * Representation of an MPLS Packet.
27 */
sanghob35a6192015-04-01 13:05:26 -070028public class MPLS extends BasePacket {
Jonathan Hart2a655752015-04-07 16:46:33 -070029 public static final int HEADER_LENGTH = 4;
30
sanghob35a6192015-04-01 13:05:26 -070031 public static final byte PROTOCOL_IPV4 = 0x1;
32 public static final byte PROTOCOL_MPLS = 0x6;
Jonathan Hart2a655752015-04-07 16:46:33 -070033 static Map<Byte, Deserializer<? extends IPacket>> protocolDeserializerMap
34 = new HashMap<>();
sanghob35a6192015-04-01 13:05:26 -070035
36 static {
Jonathan Hart2a655752015-04-07 16:46:33 -070037 protocolDeserializerMap.put(PROTOCOL_IPV4, IPv4.deserializer());
38 protocolDeserializerMap.put(PROTOCOL_MPLS, MPLS.deserializer());
sanghob35a6192015-04-01 13:05:26 -070039 }
40
41 protected int label; //20bits
42 protected byte bos; //1bit
43 protected byte ttl; //8bits
44 protected byte protocol;
45
46 /**
47 * Default constructor that sets the version to 4.
48 */
49 public MPLS() {
50 super();
51 this.bos = 1;
52 this.protocol = PROTOCOL_IPV4;
53 }
54
55 @Override
56 public byte[] serialize() {
57 byte[] payloadData = null;
58 if (payload != null) {
59 payload.setParent(this);
60 payloadData = payload.serialize();
61 }
62
63 byte[] data = new byte[(4 + ((payloadData != null) ? payloadData.length : 0)) ];
64 ByteBuffer bb = ByteBuffer.wrap(data);
65
66 bb.putInt(((this.label & 0x000fffff) << 12) | ((this.bos & 0x1) << 8 | (this.ttl & 0xff)));
67 if (payloadData != null) {
68 bb.put(payloadData);
69 }
70
71 return data;
72 }
73
74 @Override
75 public IPacket deserialize(byte[] data, int offset, int length) {
76 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
77
78 int mplsheader = bb.getInt();
79 this.label = ((mplsheader & 0xfffff000) >> 12);
80 this.bos = (byte) ((mplsheader & 0x00000100) >> 8);
81 this.bos = (byte) (mplsheader & 0x000000ff);
82 this.protocol = (this.bos == 1) ? PROTOCOL_IPV4 : PROTOCOL_MPLS;
83
Jonathan Hart2a655752015-04-07 16:46:33 -070084 Deserializer<? extends IPacket> deserializer;
85 if (protocolDeserializerMap.containsKey(this.protocol)) {
86 deserializer = protocolDeserializerMap.get(this.protocol);
sanghob35a6192015-04-01 13:05:26 -070087 } else {
Jonathan Hart2a655752015-04-07 16:46:33 -070088 deserializer = Data.deserializer();
sanghob35a6192015-04-01 13:05:26 -070089 }
Jonathan Hart2a655752015-04-07 16:46:33 -070090 try {
91 this.payload = deserializer.deserialize(data, bb.position(), bb.limit() - bb.position());
92 this.payload.setParent(this);
93 } catch (DeserializationException e) {
94 return this;
95 }
sanghob35a6192015-04-01 13:05:26 -070096
97 return this;
98 }
99
100 /**
101 * Returns the MPLS label.
102 *
103 * @return MPLS label
104 */
105 public int getLabel() {
106 return label;
107 }
108
109 /**
110 * Sets the MPLS label.
111 *
Thomas Vachuskae10f56b2015-04-15 18:20:08 -0700112 * @param label MPLS label
sanghob35a6192015-04-01 13:05:26 -0700113 */
114 public void setLabel(int label) {
115 this.label = label;
116 }
117
118 /**
119 * Returns the MPLS TTL of the packet.
120 *
121 * @return MPLS TTL of the packet
122 */
123 public byte getTtl() {
124 return ttl;
125 }
126
127 /**
128 * Sets the MPLS TTL of the packet.
129 *
130 * @param ttl MPLS TTL
131 */
132 public void setTtl(byte ttl) {
133 this.ttl = ttl;
134 }
135
Jonathan Hart2a655752015-04-07 16:46:33 -0700136 /**
137 * Deserializer function for MPLS packets.
138 *
139 * @return deserializer function
140 */
141 public static Deserializer<MPLS> deserializer() {
142 return (data, offset, length) -> {
143 checkInput(data, offset, length, HEADER_LENGTH);
144
145 MPLS mpls = new MPLS();
146 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
147
148 int mplsheader = bb.getInt();
149 mpls.label = ((mplsheader & 0xfffff000) >>> 12);
150 mpls.bos = (byte) ((mplsheader & 0x00000100) >> 8);
151 mpls.ttl = (byte) (mplsheader & 0x000000ff);
152 mpls.protocol = (mpls.bos == 1) ? PROTOCOL_IPV4 : PROTOCOL_MPLS;
153
154 Deserializer<? extends IPacket> deserializer;
155 if (protocolDeserializerMap.containsKey(mpls.protocol)) {
156 deserializer = protocolDeserializerMap.get(mpls.protocol);
157 } else {
158 deserializer = Data.deserializer();
159 }
160 mpls.payload = deserializer.deserialize(data, bb.position(), bb.limit() - bb.position());
161 mpls.payload.setParent(mpls);
162
163 return mpls;
164 };
165 }
Jian Li5fc14292015-12-04 11:30:46 -0800166
167 @Override
168 public String toString() {
169 return toStringHelper(getClass())
170 .add("label", Integer.toString(label))
171 .add("bos", Byte.toString(bos))
172 .add("ttl", Byte.toString(ttl))
173 .add("protocol", Byte.toString(protocol))
174 .toString();
175 }
sanghob35a6192015-04-01 13:05:26 -0700176}