예제 #1
0
파일: netutils.c 프로젝트: iceppu/padavan
const char*
get_ifname_descriptor(const char* ifname, int ap_mode, int *ifindex, int *wan_no)
{
	struct ifname_desc_t *ifd;

	for (ifd = (struct ifname_desc_t *)&ifname_descs[0]; ifd->ifname; ifd++) {
		if (ap_mode && ifd->is_router_mode)
			continue;
		if (!ap_mode && ifd->is_ap_mode)
			continue;
		if (strcmp(ifname, ifd->ifname) == 0) {
			if (wan_no)
				*wan_no = (int)ifd->wan_no;
			if (ifd->is_dynamic)
				*ifindex = get_interface_index(ifname);
			else
				*ifindex = 0;
			return ifd->ifdesc;
		}
	}

	return NULL;
}
static int set_routes(const char *name, const char *routes)
{
    int index = get_interface_index(name);
    if (index < 0) {
        return index;
    }

    rtentry rt4;
    memset(&rt4, 0, sizeof(rt4));
    rt4.rt_dev = (char *)name;
    rt4.rt_flags = RTF_UP;
    rt4.rt_dst.sa_family = AF_INET;
    rt4.rt_genmask.sa_family = AF_INET;

    in6_rtmsg rt6;
    memset(&rt6, 0, sizeof(rt6));
    rt6.rtmsg_ifindex = index;
    rt6.rtmsg_flags = RTF_UP;

    char address[65];
    int prefix;
    int chars;
    int count = 0;

    while (sscanf(routes, " %64[^/]/%d %n", address, &prefix, &chars) == 2) {
        routes += chars;

        if (strchr(address, ':')) {
            // Add an IPv6 route.
            if (inet_pton(AF_INET6, address, &rt6.rtmsg_dst) != 1 ||
                    prefix < 0 || prefix > 128) {
                count = BAD_ARGUMENT;
                break;
            }

            rt6.rtmsg_dst_len = prefix ? prefix : 1;
            if (ioctl(inet6, SIOCADDRT, &rt6) && errno != EEXIST) {
                count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
                break;
            }

            if (!prefix) {
                // Split the route instead of replacing the default route.
                rt6.rtmsg_dst.s6_addr[0] ^= 0x80;
                if (ioctl(inet6, SIOCADDRT, &rt6) && errno != EEXIST) {
                    count = SYSTEM_ERROR;
                    break;
                }
            }
        } else {
            // Add an IPv4 route.
            if (inet_pton(AF_INET, address, as_in_addr(&rt4.rt_dst)) != 1 ||
                    prefix < 0 || prefix > 32) {
                count = BAD_ARGUMENT;
                break;
            }

            in_addr_t mask = prefix ? (~0 << (32 - prefix)) : 0x80000000;
            *as_in_addr(&rt4.rt_genmask) = htonl(mask);
            if (ioctl(inet4, SIOCADDRT, &rt4) && errno != EEXIST) {
                count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
                break;
            }

            if (!prefix) {
                // Split the route instead of replacing the default route.
                *as_in_addr(&rt4.rt_dst) ^= htonl(0x80000000);
                if (ioctl(inet4, SIOCADDRT, &rt4) && errno != EEXIST) {
                    count = SYSTEM_ERROR;
                    break;
                }
            }
        }
        ALOGD("Route added on %s: %s/%d", name, address, prefix);
        ++count;
    }

    if (count == BAD_ARGUMENT) {
        ALOGE("Invalid route: %s/%d", address, prefix);
    } else if (count == SYSTEM_ERROR) {
        ALOGE("Cannot add route: %s/%d: %s",
                address, prefix, strerror(errno));
    } else if (*routes) {
        ALOGE("Invalid route: %s", routes);
        count = BAD_ARGUMENT;
    }

    return count;
}
static int set_addresses(const char *name, const char *addresses)
{
    int index = get_interface_index(name);
    if (index < 0) {
        return index;
    }

    ifreq ifr4;
    memset(&ifr4, 0, sizeof(ifr4));
    strncpy(ifr4.ifr_name, name, IFNAMSIZ);
    ifr4.ifr_addr.sa_family = AF_INET;
    ifr4.ifr_netmask.sa_family = AF_INET;

    in6_ifreq ifr6;
    memset(&ifr6, 0, sizeof(ifr6));
    ifr6.ifr6_ifindex = index;

    char address[65];
    int prefix;
    int chars;
    int count = 0;

    while (sscanf(addresses, " %64[^/]/%d %n", address, &prefix, &chars) == 2) {
        addresses += chars;

        if (strchr(address, ':')) {
            // Add an IPv6 address.
            if (inet_pton(AF_INET6, address, &ifr6.ifr6_addr) != 1 ||
                    prefix < 0 || prefix > 128) {
                count = BAD_ARGUMENT;
                break;
            }

            ifr6.ifr6_prefixlen = prefix;
            if (ioctl(inet6, SIOCSIFADDR, &ifr6)) {
                count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
                break;
            }
        } else {
            // Add an IPv4 address.
            if (inet_pton(AF_INET, address, as_in_addr(&ifr4.ifr_addr)) != 1 ||
                    prefix < 0 || prefix > 32) {
                count = BAD_ARGUMENT;
                break;
            }

            if (count) {
                sprintf(ifr4.ifr_name, "%s:%d", name, count);
            }
            if (ioctl(inet4, SIOCSIFADDR, &ifr4)) {
                count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
                break;
            }

            in_addr_t mask = prefix ? (~0 << (32 - prefix)) : 0;
            *as_in_addr(&ifr4.ifr_netmask) = htonl(mask);
            if (ioctl(inet4, SIOCSIFNETMASK, &ifr4)) {
                count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
                break;
            }
        }
        ALOGD("Address added on %s: %s/%d", name, address, prefix);
        ++count;
    }

    if (count == BAD_ARGUMENT) {
        ALOGE("Invalid address: %s/%d", address, prefix);
    } else if (count == SYSTEM_ERROR) {
        ALOGE("Cannot add address: %s/%d: %s", address, prefix, strerror(errno));
    } else if (*addresses) {
        ALOGE("Invalid address: %s", addresses);
        count = BAD_ARGUMENT;
    }

    return count;
}
예제 #4
0
int main(int argc, char** argv) {
	unsigned long my_ip, my_netmask, my_prefix, network_len, cur_ip;
	int my_index;
	struct sockaddr sa;
	int sock;
	u_char hwaddr[MAC_ADDR_LEN];
	char *ifname, *ifsend, *cindex;
	char ch;

	if (argc < 2) {
		print_usage(usage);
	}

	while ((ch = getopt(argc, argv, "d")) != -1) {
		switch(ch) {
			case 'd':
				opt_d = 1;
				break;
			case '?':
			default:
				goto args;
		}
	}

args:	argc -= optind;
	argv += optind;

	if (opt_d && !argc) {
		print_usage(usage);
	}

	// Sockets
	sock = NEWSOCKET();
	ioctl_sock = NEWSOCKET();

	// Recv timeout
	struct timeval tv;
	tv.tv_sec = 0;
	tv.tv_usec = 1;
	setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));

	if ((sock < 0) || (ioctl_sock < 0)) {
		perror("Unable to create socket");

		exit(1);
	}

	if (!(ifname = strdup(*argv)) || !(ifsend = strdup(*argv)))
		die("Cannot duplicate interface name\n");

	/*
	 * For an alias interface we use its data but we send
	 * the actual packet on corresponding real interface
	 */
	if ((cindex = strchr(ifsend, ':')))
		*cindex = '\0';

	if (opt_d) {
		printf("Interface: %s\n", ifname);
	}

	sa.sa_family = AF_INET;
	strcpy(sa.sa_data, ifsend);

	get_hw_addr(hwaddr, ifname);
	my_ip = get_ip_addr(ifname);
	my_netmask = get_ip_mask(ifname);
	my_index = get_interface_index(ifname);
	my_prefix = my_ip & my_netmask;
	network_len = my_netmask ^ 0xffffffff;

	if (opt_d) {
		printf("Prefix: %lu\n", my_prefix);
		printf("Network length: %lu\n", network_len);
	}

	for (cur_ip = my_prefix + 1; cur_ip <= my_prefix + network_len; cur_ip++) {
		if (cur_ip == my_ip) continue; // Skip gratuitous ARP

		send_arp(sock, my_index, cur_ip, my_ip, hwaddr);

		detect_sonos(sock);
	}

	exit(0);
}