125f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline/*
225f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline * Copyright (C) 2015 The Android Open Source Project
325f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline *
425f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline * Licensed under the Apache License, Version 2.0 (the "License");
525f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline * you may not use this file except in compliance with the License.
625f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline * You may obtain a copy of the License at
725f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline *
825f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline *      http://www.apache.org/licenses/LICENSE-2.0
925f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline *
1025f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline * Unless required by applicable law or agreed to in writing, software
1125f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline * distributed under the License is distributed on an "AS IS" BASIS,
1225f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1325f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline * See the License for the specific language governing permissions and
1425f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline * limitations under the License.
1525f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline */
1625f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
1725f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
1825f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline#include <android/multinetwork.h>
1925f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline#include <errno.h>
2025f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline#include <NetdClient.h>    // the functions that communicate with netd
2125f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline#include <resolv_netid.h>  // android_getaddrinfofornet()
2225f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline#include <stdlib.h>
2325f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline#include <sys/limits.h>
2425f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
2525f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
2625f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Klinestatic int getnetidfromhandle(net_handle_t handle, unsigned *netid) {
2725f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    static const uint32_t k32BitMask = 0xffffffff;
2825f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    // This value MUST be kept in sync with the corresponding value in
2925f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    // the android.net.Network#getNetworkHandle() implementation.
3025f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    static const uint32_t kHandleMagic = 0xfacade;
3125f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
3225f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    // Check for minimum acceptable version of the API in the low bits.
3325f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    if (handle != NETWORK_UNSPECIFIED &&
3425f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        (handle & k32BitMask) != kHandleMagic) {
3525f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        return 0;
3625f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    }
3725f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
3825f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    if (netid != NULL) {
3925f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        *netid = ((handle >> (CHAR_BIT * sizeof(k32BitMask))) & k32BitMask);
4025f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    }
4125f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    return 1;
4225f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline}
4325f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
4425f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
4525f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Klineint android_setsocknetwork(net_handle_t network, int fd) {
4625f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    unsigned netid;
4725f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    if (!getnetidfromhandle(network, &netid)) {
4825f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        errno = EINVAL;
4925f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        return -1;
5025f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    }
5125f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
5225f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    int rval = setNetworkForSocket(netid, fd);
5325f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    if (rval < 0) {
5425f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        errno = -rval;
5525f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        rval = -1;
5625f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    }
5725f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    return rval;
5825f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline}
5925f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
6025f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Klineint android_setprocnetwork(net_handle_t network) {
6125f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    unsigned netid;
6225f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    if (!getnetidfromhandle(network, &netid)) {
6325f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        errno = EINVAL;
6425f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        return -1;
6525f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    }
6625f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
6725f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    int rval = setNetworkForProcess(netid);
6825f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    if (rval < 0) {
6925f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        errno = -rval;
7025f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        rval = -1;
7125f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    }
7225f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    return rval;
7325f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline}
7425f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
7525f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Klineint android_getaddrinfofornetwork(net_handle_t network,
7625f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        const char *node, const char *service,
7725f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        const struct addrinfo *hints, struct addrinfo **res) {
7825f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    unsigned netid;
7925f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    if (!getnetidfromhandle(network, &netid)) {
8025f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        errno = EINVAL;
8125f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline        return EAI_SYSTEM;
8225f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    }
8325f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline
8425f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline    return android_getaddrinfofornet(node, service, hints, netid, 0, res);
8525f3b7bb2d05e4a020e7d82ada1543d2cdc75fbbErik Kline}
86