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