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