Home | History | Annotate | Download | only in android
      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 
     18 #include <android/multinetwork.h>
     19 #include <errno.h>
     20 #include <NetdClient.h>    // the functions that communicate with netd
     21 #include <resolv_netid.h>  // android_getaddrinfofornet()
     22 #include <stdlib.h>
     23 #include <sys/limits.h>
     24 
     25 
     26 static int getnetidfromhandle(net_handle_t handle, unsigned *netid) {
     27     static const uint32_t k32BitMask = 0xffffffff;
     28     // This value MUST be kept in sync with the corresponding value in
     29     // the android.net.Network#getNetworkHandle() implementation.
     30     static const uint32_t kHandleMagic = 0xfacade;
     31 
     32     // Check for minimum acceptable version of the API in the low bits.
     33     if (handle != NETWORK_UNSPECIFIED &&
     34         (handle & k32BitMask) != kHandleMagic) {
     35         return 0;
     36     }
     37 
     38     if (netid != NULL) {
     39         *netid = ((handle >> (CHAR_BIT * sizeof(k32BitMask))) & k32BitMask);
     40     }
     41     return 1;
     42 }
     43 
     44 
     45 int android_setsocknetwork(net_handle_t network, int fd) {
     46     unsigned netid;
     47     if (!getnetidfromhandle(network, &netid)) {
     48         errno = EINVAL;
     49         return -1;
     50     }
     51 
     52     int rval = setNetworkForSocket(netid, fd);
     53     if (rval < 0) {
     54         errno = -rval;
     55         rval = -1;
     56     }
     57     return rval;
     58 }
     59 
     60 int android_setprocnetwork(net_handle_t network) {
     61     unsigned netid;
     62     if (!getnetidfromhandle(network, &netid)) {
     63         errno = EINVAL;
     64         return -1;
     65     }
     66 
     67     int rval = setNetworkForProcess(netid);
     68     if (rval < 0) {
     69         errno = -rval;
     70         rval = -1;
     71     }
     72     return rval;
     73 }
     74 
     75 int android_getaddrinfofornetwork(net_handle_t network,
     76         const char *node, const char *service,
     77         const struct addrinfo *hints, struct addrinfo **res) {
     78     unsigned netid;
     79     if (!getnetidfromhandle(network, &netid)) {
     80         errno = EINVAL;
     81         return EAI_SYSTEM;
     82     }
     83 
     84     return android_getaddrinfofornet(node, service, hints, netid, 0, res);
     85 }
     86