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