1 /* 2 * Copyright (C) 2019 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.ipsec.ike; 18 19 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS; 20 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DHCP; 21 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DNS; 22 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK; 23 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_SUBNET; 24 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS; 25 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_DNS; 26 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_SUBNET; 27 28 import android.annotation.NonNull; 29 import android.annotation.SystemApi; 30 import android.net.IpPrefix; 31 import android.net.LinkAddress; 32 33 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload; 34 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute; 35 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address; 36 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dhcp; 37 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dns; 38 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask; 39 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Subnet; 40 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address; 41 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Dns; 42 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Subnet; 43 44 import java.net.InetAddress; 45 import java.util.Collections; 46 import java.util.LinkedList; 47 import java.util.List; 48 49 /** 50 * ChildSessionConfiguration represents the negotiated configuration for a Child Session. 51 * 52 * <p>Configurations include traffic selectors and internal network information. 53 * 54 * @hide 55 */ 56 @SystemApi 57 public final class ChildSessionConfiguration { 58 private static final int IPv4_DEFAULT_PREFIX_LEN = 32; 59 60 private final List<IkeTrafficSelector> mInboundTs; 61 private final List<IkeTrafficSelector> mOutboundTs; 62 private final List<LinkAddress> mInternalAddressList; 63 private final List<InetAddress> mInternalDnsAddressList; 64 private final List<IpPrefix> mSubnetAddressList; 65 private final List<InetAddress> mInternalDhcpAddressList; 66 67 /** 68 * Construct an instance of {@link ChildSessionConfiguration}. 69 * 70 * <p>It is only supported to build a {@link ChildSessionConfiguration} with a Configure(Reply) 71 * Payload. 72 * 73 * @hide 74 */ ChildSessionConfiguration( List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs, IkeConfigPayload configPayload)75 public ChildSessionConfiguration( 76 List<IkeTrafficSelector> inTs, 77 List<IkeTrafficSelector> outTs, 78 IkeConfigPayload configPayload) { 79 this(inTs, outTs); 80 81 if (configPayload.configType != IkeConfigPayload.CONFIG_TYPE_REPLY) { 82 throw new IllegalArgumentException( 83 "Cannot build ChildSessionConfiguration with configuration type: " 84 + configPayload.configType); 85 } 86 87 // It is validated in IkeConfigPayload that a config reply only has at most one non-empty 88 // netmask and netmask exists only when IPv4 internal address exists. 89 ConfigAttributeIpv4Netmask netmaskAttr = null; 90 for (ConfigAttribute att : configPayload.recognizedAttributeList) { 91 if (att.attributeType == CONFIG_ATTR_INTERNAL_IP4_NETMASK && !att.isEmptyValue()) { 92 netmaskAttr = (ConfigAttributeIpv4Netmask) att; 93 } 94 } 95 96 for (ConfigAttribute att : configPayload.recognizedAttributeList) { 97 if (att.isEmptyValue()) continue; 98 switch (att.attributeType) { 99 case CONFIG_ATTR_INTERNAL_IP4_ADDRESS: 100 ConfigAttributeIpv4Address addressAttr = (ConfigAttributeIpv4Address) att; 101 if (netmaskAttr != null) { 102 mInternalAddressList.add( 103 new LinkAddress(addressAttr.address, netmaskAttr.getPrefixLen())); 104 } else { 105 mInternalAddressList.add( 106 new LinkAddress(addressAttr.address, IPv4_DEFAULT_PREFIX_LEN)); 107 } 108 break; 109 case CONFIG_ATTR_INTERNAL_IP4_NETMASK: 110 // No action. 111 break; 112 case CONFIG_ATTR_INTERNAL_IP6_ADDRESS: 113 mInternalAddressList.add(((ConfigAttributeIpv6Address) att).linkAddress); 114 break; 115 case CONFIG_ATTR_INTERNAL_IP4_DNS: 116 mInternalDnsAddressList.add(((ConfigAttributeIpv4Dns) att).address); 117 break; 118 case CONFIG_ATTR_INTERNAL_IP6_DNS: 119 mInternalDnsAddressList.add(((ConfigAttributeIpv6Dns) att).address); 120 break; 121 case CONFIG_ATTR_INTERNAL_IP4_SUBNET: 122 ConfigAttributeIpv4Subnet ipv4SubnetAttr = (ConfigAttributeIpv4Subnet) att; 123 mSubnetAddressList.add( 124 new IpPrefix( 125 ipv4SubnetAttr.linkAddress.getAddress(), 126 ipv4SubnetAttr.linkAddress.getPrefixLength())); 127 break; 128 case CONFIG_ATTR_INTERNAL_IP6_SUBNET: 129 ConfigAttributeIpv6Subnet ipV6SubnetAttr = (ConfigAttributeIpv6Subnet) att; 130 mSubnetAddressList.add( 131 new IpPrefix( 132 ipV6SubnetAttr.linkAddress.getAddress(), 133 ipV6SubnetAttr.linkAddress.getPrefixLength())); 134 break; 135 case CONFIG_ATTR_INTERNAL_IP4_DHCP: 136 mInternalDhcpAddressList.add(((ConfigAttributeIpv4Dhcp) att).address); 137 break; 138 default: 139 // Not relevant to child session 140 } 141 } 142 } 143 144 /** 145 * Construct an instance of {@link ChildSessionConfiguration}. 146 * 147 * @hide 148 */ ChildSessionConfiguration( List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs)149 public ChildSessionConfiguration( 150 List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs) { 151 mInboundTs = Collections.unmodifiableList(inTs); 152 mOutboundTs = Collections.unmodifiableList(outTs); 153 mInternalAddressList = new LinkedList<>(); 154 mInternalDnsAddressList = new LinkedList<>(); 155 mSubnetAddressList = new LinkedList<>(); 156 mInternalDhcpAddressList = new LinkedList<>(); 157 } 158 159 /** 160 * Returns the negotiated inbound traffic selectors. 161 * 162 * <p>Only inbound traffic within the range is acceptable to the Child Session. 163 * 164 * <p>The Android platform does not support port-based routing. Port ranges of traffic selectors 165 * are only informational. 166 * 167 * @return the inbound traffic selectors. 168 */ 169 @NonNull getInboundTrafficSelectors()170 public List<IkeTrafficSelector> getInboundTrafficSelectors() { 171 return mInboundTs; 172 } 173 174 /** 175 * Returns the negotiated outbound traffic selectors. 176 * 177 * <p>Only outbound traffic within the range is acceptable to the Child Session. 178 * 179 * <p>The Android platform does not support port-based routing. Port ranges of traffic selectors 180 * are only informational. 181 * 182 * @return the outbound traffic selectors. 183 */ 184 @NonNull getOutboundTrafficSelectors()185 public List<IkeTrafficSelector> getOutboundTrafficSelectors() { 186 return mOutboundTs; 187 } 188 189 /** 190 * Returns the assigned internal addresses. 191 * 192 * @return the assigned internal addresses, or an empty list when no addresses are assigned by 193 * the remote IKE server (e.g. for a non-tunnel mode Child Session). 194 */ 195 @NonNull getInternalAddresses()196 public List<LinkAddress> getInternalAddresses() { 197 return Collections.unmodifiableList(mInternalAddressList); 198 } 199 200 /** 201 * Returns the internal subnets protected by the IKE server. 202 * 203 * @return the internal subnets, or an empty list when no information of protected subnets is 204 * provided by the IKE server (e.g. for a non-tunnel mode Child Session). 205 */ 206 @NonNull getInternalSubnets()207 public List<IpPrefix> getInternalSubnets() { 208 return Collections.unmodifiableList(mSubnetAddressList); 209 } 210 211 /** 212 * Returns the internal DNS server addresses. 213 * 214 * @return the internal DNS server addresses, or an empty list when no DNS server is provided by 215 * the IKE server (e.g. for a non-tunnel mode Child Session). 216 */ 217 @NonNull getInternalDnsServers()218 public List<InetAddress> getInternalDnsServers() { 219 return Collections.unmodifiableList(mInternalDnsAddressList); 220 } 221 222 /** 223 * Returns the internal DHCP server addresses. 224 * 225 * @return the internal DHCP server addresses, or an empty list when no DHCP server is provided 226 * by the IKE server (e.g. for a non-tunnel mode Child Session). 227 */ 228 @NonNull getInternalDhcpServers()229 public List<InetAddress> getInternalDhcpServers() { 230 return Collections.unmodifiableList(mInternalDhcpAddressList); 231 } 232 } 233