Пример #1
0
int ifc_set_prefixLength(const char *name, int prefixLength)
{
    struct ifreq ifr;
    // TODO - support ipv6
    if (prefixLength > 32 || prefixLength < 0) return -1;

    in_addr_t mask = prefixLengthToIpv4Netmask(prefixLength);
    ifc_init_ifr(name, &ifr);
    init_sockaddr_in(&ifr.ifr_addr, mask);

    return ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr);
}
Пример #2
0
int ifc_act_on_ipv4_route(int action, const char *ifname, struct in_addr dst, int prefix_length,
                          struct in_addr gw)
{
    struct rtentry rt;
    int result;
    in_addr_t netmask;

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

    rt.rt_dst.sa_family = AF_INET;
    rt.rt_dev = (void*) ifname;

    netmask = prefixLengthToIpv4Netmask(prefix_length);
    init_sockaddr_in(&rt.rt_genmask, netmask);
    init_sockaddr_in(&rt.rt_dst, dst.s_addr);
    rt.rt_flags = RTF_UP;

    if (prefix_length == 32) {
        rt.rt_flags |= RTF_HOST;
    }

    if (gw.s_addr != 0) {
        rt.rt_flags |= RTF_GATEWAY;
        init_sockaddr_in(&rt.rt_gateway, gw.s_addr);
    }

    ifc_init();

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

    result = ioctl(ifc_ctl_sock, action, &rt);
    if (result < 0) {
        if (errno == EEXIST) {
            result = 0;
        } else {
            result = -errno;
        }
    }
    ifc_close();
    return result;
}
Пример #3
0
struct ifaddrs *get_interface(const char *name, sa_family_t family)
{
    unsigned addr, flags;
    int masklen;
    struct ifaddrs *ifa;
    struct sockaddr_in *saddr = NULL;
    struct sockaddr_in *smask = NULL;
    struct sockaddr_ll *hwaddr = NULL;
    unsigned char hwbuf[ETH_ALEN];

    if (ifc_get_info(name, &addr, &masklen, &flags))
        return NULL;

    if ((family == AF_INET) && (addr == 0))
        return NULL;

    ifa = malloc(sizeof(struct ifaddrs));
    if (!ifa)
        return NULL;
    memset(ifa, 0, sizeof(struct ifaddrs));

    ifa->ifa_name = malloc(strlen(name)+1);
    if (!ifa->ifa_name) {
        free(ifa);
        return NULL;
    }
    strcpy(ifa->ifa_name, name);
    ifa->ifa_flags = flags;

    if (family == AF_INET) {
        saddr = malloc(sizeof(struct sockaddr_in));
        if (saddr) {
            saddr->sin_addr.s_addr = addr;
            saddr->sin_family = family;
        }
        ifa->ifa_addr = (struct sockaddr *)saddr;

        if (masklen != 0) {
            smask = malloc(sizeof(struct sockaddr_in));
            if (smask) {
                smask->sin_addr.s_addr = prefixLengthToIpv4Netmask(masklen);
                smask->sin_family = family;
            }
        }
        ifa->ifa_netmask = (struct sockaddr *)smask;
    } else if (family == AF_PACKET) {
        if (!ifc_get_hwaddr(name, hwbuf)) {
            hwaddr = malloc(sizeof(struct sockaddr_ll));
            if (hwaddr) {
                memset(hwaddr, 0, sizeof(struct sockaddr_ll));
                hwaddr->sll_family = family;
                /* hwaddr->sll_protocol = ETHERTYPE_IP; */
                hwaddr->sll_hatype = ARPHRD_ETHER;
                hwaddr->sll_halen = ETH_ALEN;
                memcpy(hwaddr->sll_addr, hwbuf, ETH_ALEN);
            }
        }
        ifa->ifa_addr = (struct sockaddr *)hwaddr;
        ifa->ifa_netmask = (struct sockaddr *)smask;
    }
    return ifa;
}