blob: 5827f9ec9343213e38441561bf075e24ef0c0288 [file] [log] [blame]
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +09001/*
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
17package android.net.util;
18
19import static android.system.OsConstants.SOL_SOCKET;
20import static android.system.OsConstants.SO_BINDTODEVICE;
21
Remi NGUYEN VANb7bda392019-03-06 18:02:34 +090022import android.annotation.NonNull;
23import android.annotation.Nullable;
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090024import android.annotation.SystemApi;
Remi NGUYEN VAN53b03142019-01-23 23:11:12 +090025import android.annotation.TestApi;
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +090026import android.net.MacAddress;
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090027import android.net.NetworkUtils;
28import android.system.ErrnoException;
29import android.system.NetlinkSocketAddress;
30import android.system.Os;
31import android.system.PacketSocketAddress;
Remi NGUYEN VAN249da092019-01-29 15:17:00 +090032import android.system.StructTimeval;
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090033
Remi NGUYEN VAN53b03142019-01-23 23:11:12 +090034import libcore.io.IoBridge;
35
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090036import java.io.FileDescriptor;
Remi NGUYEN VAN53b03142019-01-23 23:11:12 +090037import java.io.IOException;
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +090038import java.net.Inet4Address;
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090039import java.net.SocketAddress;
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +090040import java.net.SocketException;
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090041
42/**
43 * Collection of utilities to interact with raw sockets.
44 * @hide
45 */
46@SystemApi
Remi NGUYEN VAN53b03142019-01-23 23:11:12 +090047@TestApi
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090048public class SocketUtils {
49 /**
50 * Create a raw datagram socket that is bound to an interface.
51 *
52 * <p>Data sent through the socket will go directly to the underlying network, ignoring VPNs.
53 */
Remi NGUYEN VANb7bda392019-03-06 18:02:34 +090054 public static void bindSocketToInterface(@NonNull FileDescriptor socket, @NonNull String iface)
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090055 throws ErrnoException {
56 // SO_BINDTODEVICE actually takes a string. This works because the first member
57 // of struct ifreq is a NULL-terminated interface name.
58 // TODO: add a setsockoptString()
59 Os.setsockoptIfreq(socket, SOL_SOCKET, SO_BINDTODEVICE, iface);
60 NetworkUtils.protectFromVpn(socket);
61 }
62
63 /**
64 * Make a socket address to communicate with netlink.
65 */
66 public static SocketAddress makeNetlinkSocketAddress(int portId, int groupsMask) {
67 return new NetlinkSocketAddress(portId, groupsMask);
68 }
69
70 /**
Remi NGUYEN VAN53b03142019-01-23 23:11:12 +090071 * Make socket address that packet sockets can bind to.
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090072 */
73 public static SocketAddress makePacketSocketAddress(short protocol, int ifIndex) {
74 return new PacketSocketAddress(protocol, ifIndex);
75 }
76
77 /**
Remi NGUYEN VAN53b03142019-01-23 23:11:12 +090078 * Make a socket address that packet socket can send packets to.
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090079 */
Remi NGUYEN VANb7bda392019-03-06 18:02:34 +090080 public static SocketAddress makePacketSocketAddress(int ifIndex, @NonNull byte[] hwAddr) {
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +090081 return new PacketSocketAddress(ifIndex, hwAddr);
82 }
83
Remi NGUYEN VAN53b03142019-01-23 23:11:12 +090084 /**
Remi NGUYEN VAN249da092019-01-29 15:17:00 +090085 * Set an option on a socket that takes a time value argument.
86 */
87 public static void setSocketTimeValueOption(
Remi NGUYEN VANb7bda392019-03-06 18:02:34 +090088 @NonNull FileDescriptor fd, int level, int option, long millis) throws ErrnoException {
Remi NGUYEN VAN249da092019-01-29 15:17:00 +090089 Os.setsockoptTimeval(fd, level, option, StructTimeval.fromMillis(millis));
90 }
91
92 /**
Remi NGUYEN VAN53b03142019-01-23 23:11:12 +090093 * @see IoBridge#closeAndSignalBlockedThreads(FileDescriptor)
94 */
Remi NGUYEN VANb7bda392019-03-06 18:02:34 +090095 public static void closeSocket(@Nullable FileDescriptor fd) throws IOException {
Remi NGUYEN VAN53b03142019-01-23 23:11:12 +090096 IoBridge.closeAndSignalBlockedThreads(fd);
97 }
98
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +090099 /**
100 * Attaches a socket filter that accepts DHCP packets to the given socket.
101 */
Remi NGUYEN VANb7bda392019-03-06 18:02:34 +0900102 public static void attachDhcpFilter(@NonNull FileDescriptor fd) throws SocketException {
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +0900103 NetworkUtils.attachDhcpFilter(fd);
104 }
105
106 /**
107 * Attaches a socket filter that accepts ICMPv6 router advertisements to the given socket.
108 * @param fd the socket's {@link FileDescriptor}.
109 * @param packetType the hardware address type, one of ARPHRD_*.
110 */
Remi NGUYEN VANb7bda392019-03-06 18:02:34 +0900111 public static void attachRaFilter(@NonNull FileDescriptor fd, int packetType)
112 throws SocketException {
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +0900113 NetworkUtils.attachRaFilter(fd, packetType);
114 }
115
116 /**
117 * Attaches a socket filter that accepts L2-L4 signaling traffic required for IP connectivity.
118 *
119 * This includes: all ARP, ICMPv6 RS/RA/NS/NA messages, and DHCPv4 exchanges.
120 *
121 * @param fd the socket's {@link FileDescriptor}.
122 * @param packetType the hardware address type, one of ARPHRD_*.
123 */
Remi NGUYEN VANb7bda392019-03-06 18:02:34 +0900124 public static void attachControlPacketFilter(@NonNull FileDescriptor fd, int packetType)
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +0900125 throws SocketException {
126 NetworkUtils.attachControlPacketFilter(fd, packetType);
127 }
128
129 /**
130 * Add an entry into the ARP cache.
131 */
Remi NGUYEN VANb7bda392019-03-06 18:02:34 +0900132 public static void addArpEntry(@NonNull Inet4Address ipv4Addr, @NonNull MacAddress ethAddr,
133 @NonNull String ifname, @NonNull FileDescriptor fd) throws IOException {
Remi NGUYEN VAN5c5f1ba2019-01-29 12:08:43 +0900134 NetworkUtils.addArpEntry(ipv4Addr, ethAddr, ifname, fd);
135 }
136
Remi NGUYEN VAN811f6382019-01-20 12:08:21 +0900137 private SocketUtils() {}
138}