1 // 2 // This file is part of the OpenNMS(R) Application. 3 // 4 // OpenNMS(R) is Copyright (C) 2002-2003 The OpenNMS Group, Inc. All rights reserved. 5 // OpenNMS(R) is a derivative work, containing both original code, included code and modified 6 // code that was published under the GNU General Public License. Copyrights for modified 7 // and included code are below. 8 // 9 // OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. 10 // 11 // Modifications: 12 // 13 // 2003 Mar 05: Changes to support response times and more platforms. 14 // 15 // Original code base Copyright (C) 1999-2001 Oculan Corp. All rights reserved. 16 // 17 // This program is free software; you can redistribute it and/or modify 18 // it under the terms of the GNU General Public License as published by 19 // the Free Software Foundation; either version 2 of the License, or 20 // (at your option) any later version. 21 // 22 // This program is distributed in the hope that it will be useful, 23 // but WITHOUT ANY WARRANTY; without even the implied warranty of 24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 // GNU General Public License for more details. 26 // 27 // You should have received a copy of the GNU General Public License 28 // along with this program; if not, write to the Free Software 29 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 30 // 31 // For more information contact: 32 // OpenNMS Licensing <license@opennms.org> 33 // http://www.opennms.org/ 34 // http://www.opennms.com/ 35 // 36 // Tab Size = 8 37 // 38 39 package org.opennms.protocols.icmp; 40 41 import org.opennms.protocols.ip.IPHeader; 42 43 /** 44 * Defines the default error handler object for processing ICMP error messages. 45 * All error messages follow the same format. The first 8 bytes is the ICMP 46 * header. Immediantly after the ICMP header is the IP packet in error, 47 * including any option data. After the IP header is the first 8 bytes of 48 * protocol data. This is enough to hold a UDP header or the first 8 bytes of a 49 * TCP header. 50 * 51 * @author <a href="mailto:weave@oculan.com">Brian Weaver </a> 52 * 53 */ 54 public class ErrorMessage extends ICMPHeader { 55 private IPHeader m_iphdr; 56 57 private byte[] m_protoData; 58 59 /** 60 * Creates a new ICMP Error Message object. 61 * 62 * @param type 63 * The ICMP type. 64 * @param code 65 * The specific code for the message. 66 * 67 */ ErrorMessage(byte type, byte code)68 protected ErrorMessage(byte type, byte code) { 69 super(type, code); 70 m_iphdr = null; 71 m_protoData = null; 72 } 73 74 /** 75 * Creates a new ICMP timestamp reply from the spcified data at the specific 76 * offset. 77 * 78 * @param buf 79 * The buffer containing the data. 80 * @param offset 81 * The start of the icmp data. 82 * 83 * @exception java.lang.IndexOutOfBoundsException 84 * Thrown if there is not sufficent data in the buffer. 85 */ ErrorMessage(byte[] buf, int offset)86 public ErrorMessage(byte[] buf, int offset) { 87 super(); 88 loadFromBuffer(buf, offset); 89 } 90 91 /** 92 * Reads the ICMP Address Mask Reqeust from the specified buffer and sets 93 * the internal fields equal to the data. If the buffer does not have 94 * sufficent data to restore the header then an IndexOutOfBoundsException is 95 * thrown by the method. If the buffer does not contain an address mask 96 * reqeust then an IllegalArgumentException is thrown. 97 * 98 * @param buf 99 * The buffer to read the data from. 100 * @param offset 101 * The offset to start reading data. 102 * 103 * @return The new offset after reading the data. 104 * 105 * @exception java.lang.IndexOutOfBoundsException 106 * Thrown if there is not sufficent data in the buffer. 107 */ loadFromBuffer(byte[] buf, int offset)108 public final int loadFromBuffer(byte[] buf, int offset) { 109 // 110 // minimum length 111 // 112 if (buf.length < (offset + 36)) 113 throw new IndexOutOfBoundsException("Insufficient data to load ICMP error message"); 114 115 offset = super.loadFromBuffer(buf, offset); 116 117 // 118 // create the header 119 // 120 m_iphdr = new IPHeader(buf, offset); 121 122 // 123 // check the minimum length again 124 // 125 if (buf.length < (offset + 16 + m_iphdr.getHeaderLength())) 126 throw new IndexOutOfBoundsException("Insufficient data to load ICMP error message"); 127 128 offset += m_iphdr.getHeaderLength(); 129 130 // 131 // load the extra 8-bytes 132 // 133 m_protoData = new byte[8]; 134 for (int x = 0; x < 8; x++) { 135 m_protoData[x] = buf[offset++]; 136 } 137 138 return offset; 139 } 140 141 /** 142 * Used to access the IP Header that caused the ICMP error message to be 143 * generated. 144 * 145 * @return The IP Header in error. 146 * 147 */ getIPHeader()148 public final IPHeader getIPHeader() { 149 return m_iphdr; 150 } 151 152 /** 153 * Sets the IP header in error. 154 * 155 * @param hdr 156 * The IP header in error 157 */ setIPHeader(IPHeader hdr)158 protected void setIPHeader(IPHeader hdr) { 159 m_iphdr = hdr; 160 } 161 162 /** 163 * Retreives the 8 bytes of protocol data that caused the error. 164 * 165 * @return The first 8 bytes of the packet in error. 166 * 167 */ getProtocolData()168 public final byte[] getProtocolData() { 169 return m_protoData; 170 } 171 172 /** 173 * Sets the protocol data that caused the error. 174 * 175 * @param pd 176 * The 8 bytes of protocol data. 177 * 178 * @exception java.lang.IndexOutOfBoundsException 179 * Thrown when pd.length is less than 8. 180 * @exception java.lang.IllegalArgumentException 181 * Thrown when pd.length is greater than 8. 182 * 183 */ setProtocolData(byte[] pd)184 protected void setProtocolData(byte[] pd) { 185 if (pd.length < 8) 186 throw new IndexOutOfBoundsException("Protocol data must be 8 bytes in length"); 187 188 if (pd.length > 8) 189 throw new IllegalArgumentException("Protocol data cannot be more than 8 bytes in length"); 190 191 m_protoData = pd; 192 } 193 } 194