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 = 0xcafed00d;
     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 
     87 int android_res_nquery(net_handle_t network, const char *dname,
     88         int ns_class, int ns_type, enum ResNsendFlags flags) {
     89     unsigned netid;
     90     if (!getnetidfromhandle(network, &netid)) {
     91         return -ENONET;
     92     }
     93 
     94     return resNetworkQuery(netid, dname, ns_class, ns_type, flags);
     95 }
     96 
     97 int android_res_nresult(int fd, int *rcode, uint8_t *answer, size_t anslen) {
     98     return resNetworkResult(fd, rcode, answer, anslen);
     99 }
    100 
    101 int android_res_nsend(net_handle_t network, const uint8_t *msg, size_t msglen,
    102         enum ResNsendFlags flags) {
    103     unsigned netid;
    104     if (!getnetidfromhandle(network, &netid)) {
    105         return -ENONET;
    106     }
    107 
    108     return resNetworkSend(netid, msg, msglen, flags);
    109 }
    110 
    111 void android_res_cancel(int nsend_fd) {
    112     resNetworkCancel(nsend_fd);
    113 }
    114