1 /*
2  * Copyright (c) 1995, 2020, 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  * <p>
39  * Unless otherwise specified, passing a {@code null} argument causes
40  * a {@link NullPointerException NullPointerException} to be thrown.
41  *
42  * <p>
43  * Methods and constructors of {@code DatagramPacket} accept parameters
44  * of type {@link SocketAddress}. {@code DatagramPacket} supports
45  * {@link InetSocketAddress}, and may support additional {@code SocketAddress}
46  * sub-types.
47  *
48  * @author  Pavani Diwanji
49  * @author  Benjamin Renaud
50  * @since   1.0
51  */
52 public final
53 class DatagramPacket {
54 
55     /**
56      * Perform class initialization
57      */
58     static {
59         jdk.internal.loader.BootLoader.loadLibrary("net");
init()60         init();
61     }
62 
63     /*
64      * The fields of this class are package-private since DatagramSocketImpl
65      * classes needs to access them.
66      */
67     byte[] buf;
68     int offset;
69     int length;
70     int bufLength;
71     InetAddress address;
72     int port;
73 
74     /**
75      * Constructs a {@code DatagramPacket} for receiving packets of
76      * length {@code length}, specifying an offset into the buffer.
77      * <p>
78      * The {@code length} argument must be less than or equal to
79      * {@code buf.length}.
80      *
81      * @param   buf     buffer for holding the incoming datagram.
82      * @param   offset  the offset for the buffer
83      * @param   length  the number of bytes to read.
84      *
85      * @throws  IllegalArgumentException    if the length or offset
86      *          is negative, or if the length plus the offset is
87      *          greater than the length of the packet's given buffer.
88      *
89      * @since   1.2
90      */
DatagramPacket(byte buf[], int offset, int length)91     public DatagramPacket(byte buf[], int offset, int length) {
92         setData(buf, offset, length);
93     }
94 
95     /**
96      * Constructs a {@code DatagramPacket} for receiving packets of
97      * length {@code length}.
98      * <p>
99      * The {@code length} argument must be less than or equal to
100      * {@code buf.length}.
101      *
102      * @param   buf     buffer for holding the incoming datagram.
103      * @param   length  the number of bytes to read.
104      *
105      * @throws  IllegalArgumentException    if the length is negative
106      *          or if the length is greater than the length of the
107      *          packet's given buffer.
108      */
DatagramPacket(byte buf[], int length)109     public DatagramPacket(byte buf[], int length) {
110         this (buf, 0, length);
111     }
112 
113     /**
114      * Constructs a datagram packet for sending packets of length
115      * {@code length} with offset {@code offset} to the
116      * specified port number on the specified host. The
117      * {@code length} argument must be less than or equal to
118      * {@code buf.length}.
119      *
120      * @param   buf     the packet data.
121      * @param   offset  the packet data offset.
122      * @param   length  the packet data length.
123      * @param   address the destination address, or {@code null}.
124      * @param   port    the destination port number.
125      *
126      * @throws  IllegalArgumentException    if the length or offset
127      *          is negative, or if the length plus the offset is
128      *          greater than the length of the packet's given buffer,
129      *          or if the port is out of range.
130      *
131      * @see     java.net.InetAddress
132      *
133      * @since   1.2
134      */
DatagramPacket(byte buf[], int offset, int length, InetAddress address, int port)135     public DatagramPacket(byte buf[], int offset, int length,
136                           InetAddress address, int port) {
137         setData(buf, offset, length);
138         setAddress(address);
139         setPort(port);
140     }
141 
142     /**
143      * Constructs a datagram packet for sending packets of length
144      * {@code length} with offset {@code offset} to the
145      * specified port number on the specified host. The
146      * {@code length} argument must be less than or equal to
147      * {@code buf.length}.
148      *
149      * @param   buf     the packet data.
150      * @param   offset  the packet data offset.
151      * @param   length  the packet data length.
152      * @param   address the destination socket address.
153      *
154      * @throws  IllegalArgumentException    if address is null or its
155      *          type is not supported, or if the length or offset is
156      *          negative, or if the length plus the offset is greater
157      *          than the length of the packet's given buffer.
158      *
159      * @see     java.net.InetAddress
160      *
161      * @since   1.4
162      */
DatagramPacket(byte buf[], int offset, int length, SocketAddress address)163     public DatagramPacket(byte buf[], int offset, int length, SocketAddress address) {
164         setData(buf, offset, length);
165         setSocketAddress(address);
166     }
167 
168     /**
169      * Constructs a datagram packet for sending packets of length
170      * {@code length} to the specified port number on the specified
171      * host. The {@code length} argument must be less than or equal
172      * to {@code buf.length}.
173      *
174      * @param   buf     the packet data.
175      * @param   length  the packet length.
176      * @param   address the destination address, or {@code null}.
177      * @param   port    the destination port number.
178      *
179      * @throws  IllegalArgumentException    if the length is negative,
180      *          or if the length is greater than the length of the
181      *          packet's given buffer, or if the port is out of range.
182      *
183      * @see     java.net.InetAddress
184      */
DatagramPacket(byte buf[], int length, InetAddress address, int port)185     public DatagramPacket(byte buf[], int length,
186                           InetAddress address, int port) {
187         this(buf, 0, length, address, port);
188     }
189 
190     /**
191      * Constructs a datagram packet for sending packets of length
192      * {@code length} to the specified port number on the specified
193      * host. The {@code length} argument must be less than or equal
194      * to {@code buf.length}.
195      *
196      * @param   buf     the packet data.
197      * @param   length  the packet length.
198      * @param   address the destination address.
199      *
200      * @throws  IllegalArgumentException    if address is null or its type is
201      *          not supported, or if the length is negative, or if the length
202      *          is greater than the length of the packet's given buffer, or
203      *          if the port is out of range.
204      *
205      * @see     java.net.InetAddress
206      *
207      * @since   1.4
208      */
DatagramPacket(byte buf[], int length, SocketAddress address)209     public DatagramPacket(byte buf[], int length, SocketAddress address) {
210         this(buf, 0, length, address);
211     }
212 
213     /**
214      * Returns the IP address of the machine to which this datagram is being
215      * sent or from which the datagram was received, or {@code null} if not
216      * set.
217      *
218      * @return  the IP address of the machine to which this datagram is being
219      *          sent or from which the datagram was received.
220      * @see     java.net.InetAddress
221      * @see #setAddress(java.net.InetAddress)
222      */
getAddress()223     public synchronized InetAddress getAddress() {
224         return address;
225     }
226 
227     /**
228      * Returns the port number on the remote host to which this datagram is
229      * being sent or from which the datagram was received, or 0 if not set.
230      *
231      * @return  the port number on the remote host to which this datagram is
232      *          being sent or from which the datagram was received.
233      * @see #setPort(int)
234      */
getPort()235     public synchronized int getPort() {
236         return port;
237     }
238 
239     /**
240      * Returns the data buffer. The data received or the data to be sent
241      * starts from the {@code offset} in the buffer,
242      * and runs for {@code length} long.
243      *
244      * @return  the buffer used to receive or  send data
245      * @see #setData(byte[], int, int)
246      */
getData()247     public synchronized byte[] getData() {
248         return buf;
249     }
250 
251     /**
252      * Returns the offset of the data to be sent or the offset of the
253      * data received.
254      *
255      * @return  the offset of the data to be sent or the offset of the
256      *          data received.
257      *
258      * @since 1.2
259      */
getOffset()260     public synchronized int getOffset() {
261         return offset;
262     }
263 
264     /**
265      * Returns the length of the data to be sent or the length of the
266      * data received.
267      *
268      * @return  the length of the data to be sent or the length of the
269      *          data received.
270      * @see #setLength(int)
271      */
getLength()272     public synchronized int getLength() {
273         return length;
274     }
275 
276     /**
277      * Set the data buffer for this packet. This sets the
278      * data, length and offset of the packet.
279      *
280      * @param   buf     the buffer to set for this packet
281      * @param   offset  the offset into the data
282      * @param   length  the length of the data
283      *          and/or the length of the buffer used to receive data
284      *
285      * @throws  IllegalArgumentException    if the length or offset
286      *          is negative, or if the length plus the offset is
287      *          greater than the length of the packet's given buffer.
288      *
289      * @see     #getData
290      * @see     #getOffset
291      * @see     #getLength
292      *
293      * @since   1.2
294      */
setData(byte[] buf, int offset, int length)295     public synchronized void setData(byte[] buf, int offset, int length) {
296         /* this will check to see if buf is null */
297         if (length < 0 || offset < 0 ||
298             (length + offset) < 0 ||
299             ((length + offset) > buf.length)) {
300             throw new IllegalArgumentException("illegal length or offset");
301         }
302         this.buf = buf;
303         this.length = length;
304         this.bufLength = length;
305         this.offset = offset;
306     }
307 
308     /**
309      * Sets the IP address of the machine to which this datagram
310      * is being sent.
311      *
312      * @param   iaddr   the {@code InetAddress}, or {@code null}.
313      *
314      * @see     #getAddress()
315      *
316      * @since   1.1
317      */
setAddress(InetAddress iaddr)318     public synchronized void setAddress(InetAddress iaddr) {
319         address = iaddr;
320     }
321 
322     /**
323      * Sets the port number on the remote host to which this datagram
324      * is being sent.
325      *
326      * @param   iport   the port number
327      *
328      * @throws  IllegalArgumentException    if the port is out of range
329      *
330      * @see     #getPort()
331      *
332      * @since   1.1
333      */
setPort(int iport)334     public synchronized void setPort(int iport) {
335         if (iport < 0 || iport > 0xFFFF) {
336             throw new IllegalArgumentException("Port out of range:"+ iport);
337         }
338         port = iport;
339     }
340 
341     /**
342      * Sets the SocketAddress (usually IP address + port number) of the remote
343      * host to which this datagram is being sent.
344      *
345      * @param   address the {@code SocketAddress}
346      *
347      * @throws  IllegalArgumentException    if address is null or is a
348      *          SocketAddress subclass not supported.
349      *
350      * @see     #getSocketAddress
351      *
352      * @since   1.4
353      */
setSocketAddress(SocketAddress address)354     public synchronized void setSocketAddress(SocketAddress address) {
355         if (address == null || !(address instanceof InetSocketAddress))
356             throw new IllegalArgumentException("unsupported address type");
357         InetSocketAddress addr = (InetSocketAddress) address;
358         if (addr.isUnresolved())
359             throw new IllegalArgumentException("unresolved address");
360         setAddress(addr.getAddress());
361         setPort(addr.getPort());
362     }
363 
364     /**
365      * Returns the {@link InetSocketAddress#InetSocketAddress(InetAddress, int)
366      * SocketAddress} (usually {@linkplain #getAddress() IP address} +
367      * {@linkplain #getPort() port number}) of the remote host that this packet
368      * is being sent to or is coming from.
369      *
370      * @return  the {@code SocketAddress}
371      *
372      * @see     #setSocketAddress
373      *
374      * @since   1.4
375      */
getSocketAddress()376     public synchronized SocketAddress getSocketAddress() {
377         return new InetSocketAddress(getAddress(), getPort());
378     }
379 
380     /**
381      * Set the data buffer for this packet. With the offset of
382      * this DatagramPacket set to 0, and the length set to
383      * the length of {@code buf}.
384      *
385      * @param   buf     the buffer to set for this packet.
386      *
387      * @see     #getLength
388      * @see     #getData
389      *
390      * @since   1.1
391      */
setData(byte[] buf)392     public synchronized void setData(byte[] buf) {
393         if (buf == null) {
394             throw new NullPointerException("null packet buffer");
395         }
396         this.buf = buf;
397         this.offset = 0;
398         this.length = buf.length;
399         this.bufLength = buf.length;
400     }
401 
402     /**
403      * Set the length for this packet. The length of the packet is
404      * the number of bytes from the packet's data buffer that will be
405      * sent, or the number of bytes of the packet's data buffer that
406      * will be used for receiving data. The length must be lesser or
407      * equal to the offset plus the length of the packet's buffer.
408      *
409      * @param   length      the length to set for this packet.
410      *
411      * @throws  IllegalArgumentException    if the length is negative,
412      *          or if the length plus the offset is greater than the
413      *          length of the packet's data buffer.
414      *
415      * @see     #getLength
416      * @see     #setData
417      *
418      * @since   1.1
419      */
setLength(int length)420     public synchronized void setLength(int length) {
421         if ((length + offset) > buf.length || length < 0 ||
422             (length + offset) < 0) {
423             throw new IllegalArgumentException("illegal length");
424         }
425         this.length = length;
426         this.bufLength = this.length;
427     }
428 
429     /**
430      * Perform class load-time initializations.
431      */
init()432     private static native void init();
433 }
434