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.util; 18 19 import static android.system.OsConstants.SOL_SOCKET; 20 import static android.system.OsConstants.SO_BINDTODEVICE; 21 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.SystemApi; 25 import android.system.ErrnoException; 26 import android.system.NetlinkSocketAddress; 27 import android.system.Os; 28 import android.system.PacketSocketAddress; 29 30 import com.android.internal.net.NetworkUtilsInternal; 31 32 import libcore.io.IoBridge; 33 34 import java.io.FileDescriptor; 35 import java.io.IOException; 36 import java.net.SocketAddress; 37 38 /** 39 * Collection of utilities to interact with raw sockets. 40 * @hide 41 */ 42 @SystemApi 43 public final class SocketUtils { 44 /** 45 * Create a raw datagram socket that is bound to an interface. 46 * 47 * <p>Data sent through the socket will go directly to the underlying network, ignoring VPNs. 48 */ bindSocketToInterface(@onNull FileDescriptor socket, @NonNull String iface)49 public static void bindSocketToInterface(@NonNull FileDescriptor socket, @NonNull String iface) 50 throws ErrnoException { 51 // SO_BINDTODEVICE actually takes a string. This works because the first member 52 // of struct ifreq is a NULL-terminated interface name. 53 // TODO: add a setsockoptString() 54 Os.setsockoptIfreq(socket, SOL_SOCKET, SO_BINDTODEVICE, iface); 55 NetworkUtilsInternal.protectFromVpn(socket); 56 } 57 58 /** 59 * Make a socket address to communicate with netlink. 60 */ 61 @NonNull makeNetlinkSocketAddress(int portId, int groupsMask)62 public static SocketAddress makeNetlinkSocketAddress(int portId, int groupsMask) { 63 return new NetlinkSocketAddress(portId, groupsMask); 64 } 65 66 /** 67 * Make socket address that packet sockets can bind to. 68 * 69 * @param protocol the layer 2 protocol of the packets to receive. One of the {@code ETH_P_*} 70 * constants in {@link android.system.OsConstants}. 71 * @param ifIndex the interface index on which packets will be received. 72 */ 73 @NonNull makePacketSocketAddress(int protocol, int ifIndex)74 public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex) { 75 return new PacketSocketAddress( 76 protocol /* sll_protocol */, 77 ifIndex /* sll_ifindex */, 78 null /* sll_addr */); 79 } 80 81 /** 82 * Make a socket address that packet socket can send packets to. 83 * @deprecated Use {@link #makePacketSocketAddress(int, int, byte[])} instead. 84 * 85 * @param ifIndex the interface index on which packets will be sent. 86 * @param hwAddr the hardware address to which packets will be sent. 87 */ 88 @Deprecated 89 @NonNull makePacketSocketAddress(int ifIndex, @NonNull byte[] hwAddr)90 public static SocketAddress makePacketSocketAddress(int ifIndex, @NonNull byte[] hwAddr) { 91 return new PacketSocketAddress( 92 0 /* sll_protocol */, 93 ifIndex /* sll_ifindex */, 94 hwAddr /* sll_addr */); 95 } 96 97 /** 98 * Make a socket address that a packet socket can send packets to. 99 * 100 * @param protocol the layer 2 protocol of the packets to send. One of the {@code ETH_P_*} 101 * constants in {@link android.system.OsConstants}. 102 * @param ifIndex the interface index on which packets will be sent. 103 * @param hwAddr the hardware address to which packets will be sent. 104 */ 105 @NonNull makePacketSocketAddress(int protocol, int ifIndex, @NonNull byte[] hwAddr)106 public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex, 107 @NonNull byte[] hwAddr) { 108 return new PacketSocketAddress( 109 protocol /* sll_protocol */, 110 ifIndex /* sll_ifindex */, 111 hwAddr /* sll_addr */); 112 } 113 114 /** 115 * @see IoBridge#closeAndSignalBlockedThreads(FileDescriptor) 116 */ closeSocket(@ullable FileDescriptor fd)117 public static void closeSocket(@Nullable FileDescriptor fd) throws IOException { 118 IoBridge.closeAndSignalBlockedThreads(fd); 119 } 120 SocketUtils()121 private SocketUtils() {} 122 } 123