1 /*
   2  * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.net;
  27 
  28 /**
  29  * This class represents a datagram packet.
  30  * <p>
  31  * Datagram packets are used to implement a connectionless packet
  32  * delivery service. Each message is routed from one machine to
  33  * another based solely on information contained within that packet.
  34  * Multiple packets sent from one machine to another might be routed
  35  * differently, and might arrive in any order. Packet delivery is
  36  * not guaranteed.
  37  *
  38  * @author  Pavani Diwanji
  39  * @author  Benjamin Renaud
  40  * @since   1.0
  41  */
  42 public final
  43 class DatagramPacket {
  44 
  45     /**
  46      * Perform class initialization
  47      */
  48     static {
  49         jdk.internal.access.SharedSecrets.getJavaLangAccess()
  50                 .loadLibrary(DatagramPacket.class, "net");
  51         init();
  52     }
  53 
  54     /*
  55      * The fields of this class are package-private since DatagramSocketImpl
  56      * classes needs to access them.
  57      */
  58     byte[] buf;
  59     int offset;
  60     int length;
  61     int bufLength;
  62     InetAddress address;
  63     int port;
  64 
  65     /**
  66      * Constructs a {@code DatagramPacket} for receiving packets of
  67      * length {@code length}, specifying an offset into the buffer.
  68      * <p>
  69      * The {@code length} argument must be less than or equal to
  70      * {@code buf.length}.
  71      *
  72      * @param   buf      buffer for holding the incoming datagram.
  73      * @param   offset   the offset for the buffer
  74      * @param   length   the number of bytes to read.
  75      *
  76      * @since 1.2
  77      */
  78     public DatagramPacket(byte buf[], int offset, int length) {
  79         setData(buf, offset, length);
  80         this.address = null;
  81         this.port = -1;
  82     }
  83 
  84     /**
  85      * Constructs a {@code DatagramPacket} for receiving packets of
  86      * length {@code length}.
  87      * <p>
  88      * The {@code length} argument must be less than or equal to
  89      * {@code buf.length}.
  90      *
  91      * @param   buf      buffer for holding the incoming datagram.
  92      * @param   length   the number of bytes to read.
  93      */
  94     public DatagramPacket(byte buf[], int length) {
  95         this (buf, 0, length);
  96     }
  97 
  98     /**
  99      * Constructs a datagram packet for sending packets of length
 100      * {@code length} with offset {@code offset} to the
 101      * specified port number on the specified host. The
 102      * {@code length} argument must be less than or equal to
 103      * {@code buf.length}.
 104      *
 105      * @param   buf      the packet data.
 106      * @param   offset   the packet data offset.
 107      * @param   length   the packet data length.
 108      * @param   address  the destination address.
 109      * @param   port     the destination port number.
 110      * @see java.net.InetAddress
 111      *
 112      * @since 1.2
 113      */
 114     public DatagramPacket(byte buf[], int offset, int length,
 115                           InetAddress address, int port) {
 116         setData(buf, offset, length);
 117         setAddress(address);
 118         setPort(port);
 119     }
 120 
 121     /**
 122      * Constructs a datagram packet for sending packets of length
 123      * {@code length} with offset {@code offset} to the
 124      * specified port number on the specified host. The
 125      * {@code length} argument must be less than or equal to
 126      * {@code buf.length}.
 127      *
 128      * @param   buf      the packet data.
 129      * @param   offset   the packet data offset.
 130      * @param   length   the packet data length.
 131      * @param   address  the destination socket address.
 132      * @throws  IllegalArgumentException if address type is not supported
 133      * @see java.net.InetAddress
 134      *
 135      * @since 1.4
 136      */
 137     public DatagramPacket(byte buf[], int offset, int length, SocketAddress address) {
 138         setData(buf, offset, length);
 139         setSocketAddress(address);
 140     }
 141 
 142     /**
 143      * Constructs a datagram packet for sending packets of length
 144      * {@code length} to the specified port number on the specified
 145      * host. The {@code length} argument must be less than or equal
 146      * to {@code buf.length}.
 147      *
 148      * @param   buf      the packet data.
 149      * @param   length   the packet length.
 150      * @param   address  the destination address.
 151      * @param   port     the destination port number.
 152      * @see     java.net.InetAddress
 153      */
 154     public DatagramPacket(byte buf[], int length,
 155                           InetAddress address, int port) {
 156         this(buf, 0, length, address, port);
 157     }
 158 
 159     /**
 160      * Constructs a datagram packet for sending packets of length
 161      * {@code length} to the specified port number on the specified
 162      * host. The {@code length} argument must be less than or equal
 163      * to {@code buf.length}.
 164      *
 165      * @param   buf      the packet data.
 166      * @param   length   the packet length.
 167      * @param   address  the destination address.
 168      * @throws  IllegalArgumentException if address type is not supported
 169      * @since 1.4
 170      * @see     java.net.InetAddress
 171      */
 172     public DatagramPacket(byte buf[], int length, SocketAddress address) {
 173         this(buf, 0, length, address);
 174     }
 175 
 176     /**
 177      * Returns the IP address of the machine to which this datagram is being
 178      * sent or from which the datagram was received.
 179      *
 180      * @return  the IP address of the machine to which this datagram is being
 181      *          sent or from which the datagram was received.
 182      * @see     java.net.InetAddress
 183      * @see #setAddress(java.net.InetAddress)
 184      */
 185     public synchronized InetAddress getAddress() {
 186         return address;
 187     }
 188 
 189     /**
 190      * Returns the port number on the remote host to which this datagram is
 191      * being sent or from which the datagram was received.
 192      *
 193      * @return  the port number on the remote host to which this datagram is
 194      *          being sent or from which the datagram was received.
 195      * @see #setPort(int)
 196      */
 197     public synchronized int getPort() {
 198         return port;
 199     }
 200 
 201     /**
 202      * Returns the data buffer. The data received or the data to be sent
 203      * starts from the {@code offset} in the buffer,
 204      * and runs for {@code length} long.
 205      *
 206      * @return  the buffer used to receive or  send data
 207      * @see #setData(byte[], int, int)
 208      */
 209     public synchronized byte[] getData() {
 210         return buf;
 211     }
 212 
 213     /**
 214      * Returns the offset of the data to be sent or the offset of the
 215      * data received.
 216      *
 217      * @return  the offset of the data to be sent or the offset of the
 218      *          data received.
 219      *
 220      * @since 1.2
 221      */
 222     public synchronized int getOffset() {
 223         return offset;
 224     }
 225 
 226     /**
 227      * Returns the length of the data to be sent or the length of the
 228      * data received.
 229      *
 230      * @return  the length of the data to be sent or the length of the
 231      *          data received.
 232      * @see #setLength(int)
 233      */
 234     public synchronized int getLength() {
 235         return length;
 236     }
 237 
 238     /**
 239      * Set the data buffer for this packet. This sets the
 240      * data, length and offset of the packet.
 241      *
 242      * @param buf the buffer to set for this packet
 243      *
 244      * @param offset the offset into the data
 245      *
 246      * @param length the length of the data
 247      *       and/or the length of the buffer used to receive data
 248      *
 249      * @exception NullPointerException if the argument is null
 250      *
 251      * @see #getData
 252      * @see #getOffset
 253      * @see #getLength
 254      *
 255      * @since 1.2
 256      */
 257     public synchronized void setData(byte[] buf, int offset, int length) {
 258         /* this will check to see if buf is null */
 259         if (length < 0 || offset < 0 ||
 260             (length + offset) < 0 ||
 261             ((length + offset) > buf.length)) {
 262             throw new IllegalArgumentException("illegal length or offset");
 263         }
 264         this.buf = buf;
 265         this.length = length;
 266         this.bufLength = length;
 267         this.offset = offset;
 268     }
 269 
 270     /**
 271      * Sets the IP address of the machine to which this datagram
 272      * is being sent.
 273      * @param iaddr the {@code InetAddress}
 274      * @since   1.1
 275      * @see #getAddress()
 276      */
 277     public synchronized void setAddress(InetAddress iaddr) {
 278         address = iaddr;
 279     }
 280 
 281     /**
 282      * Sets the port number on the remote host to which this datagram
 283      * is being sent.
 284      * @param iport the port number
 285      * @since   1.1
 286      * @see #getPort()
 287      */
 288     public synchronized void setPort(int iport) {
 289         if (iport < 0 || iport > 0xFFFF) {
 290             throw new IllegalArgumentException("Port out of range:"+ iport);
 291         }
 292         port = iport;
 293     }
 294 
 295     /**
 296      * Sets the SocketAddress (usually IP address + port number) of the remote
 297      * host to which this datagram is being sent.
 298      *
 299      * @param address the {@code SocketAddress}
 300      * @throws  IllegalArgumentException if address is null or is a
 301      *          SocketAddress subclass not supported by this socket
 302      *
 303      * @since 1.4
 304      * @see #getSocketAddress
 305      */
 306     public synchronized void setSocketAddress(SocketAddress address) {
 307         if (address == null || !(address instanceof InetSocketAddress))
 308             throw new IllegalArgumentException("unsupported address type");
 309         InetSocketAddress addr = (InetSocketAddress) address;
 310         if (addr.isUnresolved())
 311             throw new IllegalArgumentException("unresolved address");
 312         setAddress(addr.getAddress());
 313         setPort(addr.getPort());
 314     }
 315 
 316     /**
 317      * Gets the SocketAddress (usually IP address + port number) of the remote
 318      * host that this packet is being sent to or is coming from.
 319      *
 320      * @return the {@code SocketAddress}
 321      * @since 1.4
 322      * @see #setSocketAddress
 323      */
 324     public synchronized SocketAddress getSocketAddress() {
 325         return new InetSocketAddress(getAddress(), getPort());
 326     }
 327 
 328     /**
 329      * Set the data buffer for this packet. With the offset of
 330      * this DatagramPacket set to 0, and the length set to
 331      * the length of {@code buf}.
 332      *
 333      * @param buf the buffer to set for this packet.
 334      *
 335      * @exception NullPointerException if the argument is null.
 336      *
 337      * @see #getLength
 338      * @see #getData
 339      *
 340      * @since 1.1
 341      */
 342     public synchronized void setData(byte[] buf) {
 343         if (buf == null) {
 344             throw new NullPointerException("null packet buffer");
 345         }
 346         this.buf = buf;
 347         this.offset = 0;
 348         this.length = buf.length;
 349         this.bufLength = buf.length;
 350     }
 351 
 352     /**
 353      * Set the length for this packet. The length of the packet is
 354      * the number of bytes from the packet's data buffer that will be
 355      * sent, or the number of bytes of the packet's data buffer that
 356      * will be used for receiving data. The length must be lesser or
 357      * equal to the offset plus the length of the packet's buffer.
 358      *
 359      * @param length the length to set for this packet.
 360      *
 361      * @exception IllegalArgumentException if the length is negative
 362      * of if the length is greater than the packet's data buffer
 363      * length.
 364      *
 365      * @see #getLength
 366      * @see #setData
 367      *
 368      * @since 1.1
 369      */
 370     public synchronized void setLength(int length) {
 371         if ((length + offset) > buf.length || length < 0 ||
 372             (length + offset) < 0) {
 373             throw new IllegalArgumentException("illegal length");
 374         }
 375         this.length = length;
 376         this.bufLength = this.length;
 377     }
 378 
 379     /**
 380      * Perform class load-time initializations.
 381      */
 382     private static native void init();
 383 }