1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net;
18 
19 import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
20 import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
21 
22 import android.net.SocketKeepalive.InvalidPacketException;
23 import android.net.util.IpUtils;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 import android.util.Log;
27 
28 import java.net.InetAddress;
29 
30 /**
31  * Represents the actual packets that are sent by the
32  * {@link android.net.SocketKeepalive} API.
33  *
34  * @hide
35  */
36 public class KeepalivePacketData implements Parcelable {
37     private static final String TAG = "KeepalivePacketData";
38 
39     /** Source IP address */
40     public final InetAddress srcAddress;
41 
42     /** Destination IP address */
43     public final InetAddress dstAddress;
44 
45     /** Source port */
46     public final int srcPort;
47 
48     /** Destination port */
49     public final int dstPort;
50 
51     /** Packet data. A raw byte string of packet data, not including the link-layer header. */
52     private final byte[] mPacket;
53 
54     protected static final int IPV4_HEADER_LENGTH = 20;
55     protected static final int UDP_HEADER_LENGTH = 8;
56 
57     // This should only be constructed via static factory methods, such as
58     // nattKeepalivePacket
KeepalivePacketData(InetAddress srcAddress, int srcPort, InetAddress dstAddress, int dstPort, byte[] data)59     protected KeepalivePacketData(InetAddress srcAddress, int srcPort,
60             InetAddress dstAddress, int dstPort, byte[] data) throws InvalidPacketException {
61         this.srcAddress = srcAddress;
62         this.dstAddress = dstAddress;
63         this.srcPort = srcPort;
64         this.dstPort = dstPort;
65         this.mPacket = data;
66 
67         // Check we have two IP addresses of the same family.
68         if (srcAddress == null || dstAddress == null || !srcAddress.getClass().getName()
69                 .equals(dstAddress.getClass().getName())) {
70             Log.e(TAG, "Invalid or mismatched InetAddresses in KeepalivePacketData");
71             throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
72         }
73 
74         // Check the ports.
75         if (!IpUtils.isValidUdpOrTcpPort(srcPort) || !IpUtils.isValidUdpOrTcpPort(dstPort)) {
76             Log.e(TAG, "Invalid ports in KeepalivePacketData");
77             throw new InvalidPacketException(ERROR_INVALID_PORT);
78         }
79     }
80 
getPacket()81     public byte[] getPacket() {
82         return mPacket.clone();
83     }
84 
85     /* Parcelable Implementation */
describeContents()86     public int describeContents() {
87         return 0;
88     }
89 
90     /** Write to parcel */
writeToParcel(Parcel out, int flags)91     public void writeToParcel(Parcel out, int flags) {
92         out.writeString(srcAddress.getHostAddress());
93         out.writeString(dstAddress.getHostAddress());
94         out.writeInt(srcPort);
95         out.writeInt(dstPort);
96         out.writeByteArray(mPacket);
97     }
98 
KeepalivePacketData(Parcel in)99     protected KeepalivePacketData(Parcel in) {
100         srcAddress = NetworkUtils.numericToInetAddress(in.readString());
101         dstAddress = NetworkUtils.numericToInetAddress(in.readString());
102         srcPort = in.readInt();
103         dstPort = in.readInt();
104         mPacket = in.createByteArray();
105     }
106 
107     /** Parcelable Creator */
108     public static final @android.annotation.NonNull Parcelable.Creator<KeepalivePacketData> CREATOR =
109             new Parcelable.Creator<KeepalivePacketData>() {
110                 public KeepalivePacketData createFromParcel(Parcel in) {
111                     return new KeepalivePacketData(in);
112                 }
113 
114                 public KeepalivePacketData[] newArray(int size) {
115                     return new KeepalivePacketData[size];
116                 }
117             };
118 
119 }
120