Esempio n. 1
0
int ifc_act_on_ipv6_route(int action, const char *ifname, struct in6_addr dst, int prefix_length,
                          struct in6_addr gw)
{
    struct in6_rtmsg rtmsg;
    int result;
    int ifindex;

    memset(&rtmsg, 0, sizeof(rtmsg));

    ifindex = if_nametoindex(ifname);
    if (ifindex == 0) {
        printerr("if_nametoindex() failed: interface %s\n", ifname);
        return -ENXIO;
    }

    rtmsg.rtmsg_ifindex = ifindex;
    rtmsg.rtmsg_dst = dst;
    rtmsg.rtmsg_dst_len = prefix_length;
    rtmsg.rtmsg_flags = RTF_UP;

    if (prefix_length == 128) {
        rtmsg.rtmsg_flags |= RTF_HOST;
    }

    if (memcmp(&gw, &in6addr_any, sizeof(in6addr_any))) {
        rtmsg.rtmsg_flags |= RTF_GATEWAY;
        rtmsg.rtmsg_gateway = gw;
    }

    ifc_init6();

    if (ifc_ctl_sock6 < 0) {
        return -errno;
    }

    result = ioctl(ifc_ctl_sock6, action, &rtmsg);
    if (result < 0) {
        if (errno == EEXIST) {
            result = 0;
        } else {
            result = -errno;
        }
    }
    ifc_close6();
    return result;
}
int ifc_reset_connections(const char *ifname, const int reset_mask)
{
#ifdef HAVE_ANDROID_OS
    int result, success;
    in_addr_t myaddr = 0;
    struct ifreq ifr;
    struct in6_ifreq ifr6;

    if (reset_mask & RESET_IPV4_ADDRESSES) {
        /* IPv4. Clear connections on the IP address. */
        ifc_init();
        if (!(reset_mask & RESET_IGNORE_INTERFACE_ADDRESS)) {
            ifc_get_info(ifname, &myaddr, NULL, NULL);
        }
        ifc_init_ifr(ifname, &ifr);
        init_sockaddr_in(&ifr.ifr_addr, myaddr);
        result = ioctl(ifc_ctl_sock, SIOCKILLADDR,  &ifr);
        ifc_close();
    } else {
        result = 0;
    }

    if (reset_mask & RESET_IPV6_ADDRESSES) {
        /*
         * IPv6. On Linux, when an interface goes down it loses all its IPv6
         * addresses, so we don't know which connections belonged to that interface
         * So we clear all unused IPv6 connections on the device by specifying an
         * empty IPv6 address.
         */
        ifc_init6();
        // This implicitly specifies an address of ::, i.e., kill all IPv6 sockets.
        memset(&ifr6, 0, sizeof(ifr6));
        success = ioctl(ifc_ctl_sock6, SIOCKILLADDR,  &ifr6);
        if (result == 0) {
            result = success;
        }
        ifc_close6();
    }

    return result;
#else
    return 0;
#endif
}