Java tutorial
/* * 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.onosproject.ipfix.packet; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.primitives.Shorts; /** * IPFIX Message Header. */ public class MessageHeader extends AbstractIpfixPacketEntity implements AbstractIpfixPacketInterface { private static final Logger LOGGER = Logger.getLogger(SetHeader.class.getName()); private static final int HEADER_LENGTH = 16; private static final int IPFIX_VERSION = 10; private int versionNumber; private int length; private Date exportTime; private long sequenceNumber; private long observationDomainID; private List<SetHeader> setHeaders = new ArrayList<SetHeader>(); /** * Message Header format. * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Version Number | Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Export Time | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Sequence Number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Observation Domain ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ public int getVersionNumber() { return IPFIX_VERSION; } public void setVersionNumber(int versionNumber) { this.versionNumber = versionNumber; } public int getLength() { return length; } public void setLength(int length) { this.length = length; } public Date getExportTime() { return exportTime; } public void setExportTime(Date exportTime) { this.exportTime = exportTime; } public long getSequenceNumber() { return sequenceNumber; } public void setSequenceNumber(long sequenceNumber) { this.sequenceNumber = sequenceNumber; } public long getObservationDomainID() { return observationDomainID; } public void setObservationDomainID(long observationDomainID) { this.observationDomainID = observationDomainID; } public List<SetHeader> getSetHeaders() { return setHeaders; } public void setSetHeaders(List<SetHeader> setHeaders) { this.setHeaders = setHeaders; int length = HEADER_LENGTH; for (SetHeader header : setHeaders) { length += header.getLength(); } setLength(length); } public static MessageHeader parse(byte[] data) throws HeaderException { try { if (data.length < HEADER_LENGTH) { throw new HeaderException("Data array too short."); } MessageHeader mh = new MessageHeader(); // version number byte[] versionNumber = new byte[2]; System.arraycopy(data, 0, versionNumber, 0, 2); mh.setVersionNumber(Ints.fromByteArray(versionNumber)); // length byte[] length = new byte[2]; System.arraycopy(data, 2, length, 0, 2); mh.setLength(Ints.fromByteArray(length)); // export time byte[] exportTime = new byte[4]; System.arraycopy(data, 4, exportTime, 0, 4); long secondsSinceEpoche = Longs.fromByteArray(exportTime); long milliSecondsSinceEpoche = secondsSinceEpoche * 1000; mh.setExportTime(new Date(milliSecondsSinceEpoche)); // sequence number byte[] sequenceNumber = new byte[4]; System.arraycopy(data, 8, sequenceNumber, 0, 4); mh.setSequenceNumber(Longs.fromByteArray(sequenceNumber)); // observation domain id byte[] observationDomainID = new byte[4]; System.arraycopy(data, 12, observationDomainID, 0, 4); mh.setObservationDomainID(Longs.fromByteArray(observationDomainID)); // set header int offset = HEADER_LENGTH; while ((mh.getLength() - offset) > 0) { byte[] subData = new byte[mh.getLength() - offset]; System.arraycopy(data, offset, subData, 0, subData.length); SetHeader sh = SetHeader.parse(subData); mh.getSetHeaders().add(sh); offset += sh.getLength(); } if ((mh.getLength() - offset) != 0) { LOGGER.log(Level.INFO, "Unused bytes: " + (mh.getLength() - offset)); } return mh; } catch (Exception e) { throw new HeaderException("Parse error: " + e.getMessage()); } } public byte[] getBytes() throws HeaderException { try { byte[] data = new byte[length]; // version number System.arraycopy(Shorts.toByteArray((short) versionNumber), 0, data, 0, 2); // length System.arraycopy(Shorts.toByteArray((short) length), 0, data, 2, 2); // export time System.arraycopy(Ints.toByteArray((int) exportTime.getTime() / 1000), 0, data, 4, 4); // sequence number System.arraycopy(Ints.toByteArray((int) sequenceNumber), 0, data, 8, 4); // observation domain id System.arraycopy(Ints.toByteArray((int) observationDomainID), 0, data, 12, 4); // set header int offset = HEADER_LENGTH; for (SetHeader sh : setHeaders) { byte[] temp = sh.getBytes(); System.arraycopy(temp, 0, data, offset, temp.length); offset += temp.length; } return data; } catch (Exception e) { e.printStackTrace(); throw new HeaderException("Error while generating the bytes: " + e.getMessage()); } } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("[MessageHeader]: "); sb.append("Version Number: "); sb.append(versionNumber); sb.append(", "); sb.append("Length: "); sb.append(length); sb.append(", "); sb.append("Export time: "); sb.append(exportTime); sb.append(", "); sb.append("Sequence number: "); sb.append(sequenceNumber); sb.append(", "); sb.append("Observation Domain ID: "); sb.append(observationDomainID); sb.append(", "); sb.append("SetHeaders: "); sb.append(setHeaders.size()); sb.append(", "); for (SetHeader sh : setHeaders) { sb.append(sh); sb.append(", "); } return sb.toString(); } }