Example #1
0
File: intf.c Project: OPSF/uClinux
/* XXX - aliases on IRIX don't show up in SIOCGIFCONF */
static int
_intf_get_aliases(intf_t *intf, struct intf_entry *entry)
{
    struct dnet_ifaliasreq ifra;
    struct addr *ap, *lap;

    strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name));
    addr_ntos(&entry->intf_addr, &ifra.ifra_addr);
    addr_btos(entry->intf_addr.addr_bits, &ifra.ifra_mask);
    memset(&ifra.ifra_brdaddr, 0, sizeof(ifra.ifra_brdaddr));
    ifra.ifra_cookie = 1;

    ap = entry->intf_alias_addrs;
    lap = (struct addr *)((u_char *)entry + entry->intf_len);

    while (ioctl(intf->fd, SIOCLIFADDR, &ifra) == 0 &&
            ifra.ifra_cookie > 0 && (ap + 1) < lap) {
        if (addr_ston(&ifra.ifra_addr, ap) < 0)
            break;
        ap++, entry->intf_alias_num++;
    }
    entry->intf_len = (u_char *)ap - (u_char *)entry;

    return (0);
}
Example #2
0
File: intf.c Project: OPSF/uClinux
static int
_intf_add_aliases(intf_t *intf, const struct intf_entry *entry)
{
    int i;
#ifdef SIOCAIFADDR
    struct dnet_ifaliasreq ifra;
    struct addr bcast;

    memset(&ifra, 0, sizeof(ifra));
    strlcpy(ifra.ifra_name, entry->intf_name, sizeof(ifra.ifra_name));

    for (i = 0; i < (int)entry->intf_alias_num; i++) {
        if (entry->intf_alias_addrs[i].addr_type != ADDR_TYPE_IP)
            continue;

        if (addr_ntos(&entry->intf_alias_addrs[i],
                      &ifra.ifra_addr) < 0)
            return (-1);
        addr_bcast(&entry->intf_alias_addrs[i], &bcast);
        addr_ntos(&bcast, &ifra.ifra_brdaddr);
        addr_btos(entry->intf_alias_addrs[i].addr_bits,
                  &ifra.ifra_mask);

        if (ioctl(intf->fd, SIOCAIFADDR, &ifra) < 0)
            return (-1);
    }
#else
    struct ifreq ifr;
    int n = 1;

    for (i = 0; i < entry->intf_alias_num; i++) {
        if (entry->intf_alias_addrs[i].addr_type != ADDR_TYPE_IP)
            continue;

        snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s:%d",
                 entry->intf_name, n++);
# ifdef SIOCLIFADDIF
        if (ioctl(intf->fd, SIOCLIFADDIF, &ifr) < 0)
            return (-1);
# endif
        if (addr_ntos(&entry->intf_alias_addrs[i], &ifr.ifr_addr) < 0)
            return (-1);
        if (ioctl(intf->fd, SIOCSIFADDR, &ifr) < 0)
            return (-1);
    }
    strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name));
#endif
    return (0);
}
int
route_delete(route_t *r, const struct route_entry *entry)
{
	struct rtentry rt;
	struct addr dst;
	
	memset(&rt, 0, sizeof(rt));
	rt.rt_flags = RTF_UP;

	if (ADDR_ISHOST(&entry->route_dst)) {
		rt.rt_flags |= RTF_HOST;
		memcpy(&dst, &entry->route_dst, sizeof(dst));
	} else
		addr_net(&entry->route_dst, &dst);
	
	if (addr_ntos(&dst, &rt.rt_dst) < 0 ||
	    addr_btos(entry->route_dst.addr_bits, &rt.rt_genmask) < 0)
		return (-1);
	
	return (ioctl(r->fd, SIOCDELRT, &rt));
}
Example #4
0
File: intf.c Project: OPSF/uClinux
int
intf_set(intf_t *intf, const struct intf_entry *entry)
{
    struct ifreq ifr;
    struct intf_entry *orig;
    struct addr bcast;
    u_char buf[BUFSIZ];

    orig = (struct intf_entry *)buf;
    orig->intf_len = sizeof(buf);
    strcpy(orig->intf_name, entry->intf_name);

    if (intf_get(intf, orig) < 0)
        return (-1);

    /* Delete any existing aliases. */
    if (_intf_delete_aliases(intf, orig) < 0)
        return (-1);

    /* Delete any existing addrs. */
    if (_intf_delete_addrs(intf, orig) < 0)
        return (-1);

    memset(&ifr, 0, sizeof(ifr));
    strlcpy(ifr.ifr_name, entry->intf_name, sizeof(ifr.ifr_name));

    /* Set interface MTU. */
    if (entry->intf_mtu != 0) {
        ifr.ifr_mtu = entry->intf_mtu;
#ifdef SIOCSIFMTU
        if (ioctl(intf->fd, SIOCSIFMTU, &ifr) < 0)
#endif
            return (-1);
    }
    /* Set interface address. */
    if (entry->intf_addr.addr_type == ADDR_TYPE_IP) {
#ifdef BSD
        /* XXX - why must this happen before SIOCSIFADDR? */
        if (addr_btos(entry->intf_addr.addr_bits,
                      &ifr.ifr_addr) == 0) {
            if (ioctl(intf->fd, SIOCSIFNETMASK, &ifr) < 0)
                return (-1);
        }
#endif
        if (addr_ntos(&entry->intf_addr, &ifr.ifr_addr) < 0)
            return (-1);
        if (ioctl(intf->fd, SIOCSIFADDR, &ifr) < 0 && errno != EEXIST)
            return (-1);

        if (addr_btos(entry->intf_addr.addr_bits, &ifr.ifr_addr) == 0
#ifdef __linux__
                && entry->intf_addr.addr_ip != 0
#endif
           ) {
            if (ioctl(intf->fd, SIOCSIFNETMASK, &ifr) < 0)
                return (-1);
        }
        if (addr_bcast(&entry->intf_addr, &bcast) == 0) {
            if (addr_ntos(&bcast, &ifr.ifr_broadaddr) == 0) {
                /* XXX - ignore error from non-broadcast ifs */
                ioctl(intf->fd, SIOCSIFBRDADDR, &ifr);
            }
        }
    }
    /* Set link-level address. */
    if (entry->intf_link_addr.addr_type == ADDR_TYPE_ETH &&
            addr_cmp(&entry->intf_link_addr, &orig->intf_link_addr) != 0) {
#if defined(SIOCSIFHWADDR)
        if (addr_ntos(&entry->intf_link_addr, &ifr.ifr_hwaddr) < 0)
            return (-1);
        if (ioctl(intf->fd, SIOCSIFHWADDR, &ifr) < 0)
            return (-1);
#elif defined (SIOCSIFLLADDR)
        memcpy(ifr.ifr_addr.sa_data, &entry->intf_link_addr.addr_eth,
               ETH_ADDR_LEN);
        ifr.ifr_addr.sa_len = ETH_ADDR_LEN;
        if (ioctl(intf->fd, SIOCSIFLLADDR, &ifr) < 0)
            return (-1);
#else
        eth_t *eth;

        if ((eth = eth_open(entry->intf_name)) == NULL)
            return (-1);
        if (eth_set(eth, &entry->intf_link_addr.addr_eth) < 0) {
            eth_close(eth);
            return (-1);
        }
        eth_close(eth);
#endif
    }
    /* Set point-to-point destination. */
    if (entry->intf_dst_addr.addr_type == ADDR_TYPE_IP) {
        if (addr_ntos(&entry->intf_dst_addr, &ifr.ifr_dstaddr) < 0)
            return (-1);
        if (ioctl(intf->fd, SIOCSIFDSTADDR, &ifr) < 0 &&
                errno != EEXIST)
            return (-1);
    }
    /* Add aliases. */
    if (_intf_add_aliases(intf, entry) < 0)
        return (-1);

    /* Set interface flags. */
    if (ioctl(intf->fd, SIOCGIFFLAGS, &ifr) < 0)
        return (-1);

    ifr.ifr_flags = intf_flags_to_iff(entry->intf_flags, ifr.ifr_flags);

    if (ioctl(intf->fd, SIOCSIFFLAGS, &ifr) < 0)
        return (-1);

    return (0);
}
Example #5
0
static int
route_msg(route_t *r, int type, struct addr *dst, struct addr *gw)
{
	struct addr net;
	struct rt_msghdr *rtm;
	struct sockaddr *sa;
	u_char buf[BUFSIZ];
	pid_t pid;
	int len;

	memset(buf, 0, sizeof(buf));

	rtm = (struct rt_msghdr *)buf;
	rtm->rtm_version = RTM_VERSION;
	if ((rtm->rtm_type = type) != RTM_DELETE)
		rtm->rtm_flags = RTF_UP;
	rtm->rtm_addrs = RTA_DST;
	rtm->rtm_seq = ++r->seq;

	/* Destination */
	sa = (struct sockaddr *)(rtm + 1);
	if (addr_net(dst, &net) < 0 || addr_ntos(&net, sa) < 0)
		return (-1);
	sa = NEXTSA(sa);

	/* Gateway */
	if (gw != NULL && type != RTM_GET) {
		rtm->rtm_flags |= RTF_GATEWAY;
		rtm->rtm_addrs |= RTA_GATEWAY;
		if (addr_ntos(gw, sa) < 0)
			return (-1);
		sa = NEXTSA(sa);
	}
	/* Netmask */
	if (dst->addr_ip == IP_ADDR_ANY || dst->addr_bits < IP_ADDR_BITS) {
		rtm->rtm_addrs |= RTA_NETMASK;
		if (addr_btos(dst->addr_bits, sa) < 0)
			return (-1);
		sa = NEXTSA(sa);
	} else
		rtm->rtm_flags |= RTF_HOST;
	
	rtm->rtm_msglen = (u_char *)sa - buf;
#ifdef DEBUG
	route_msg_print(rtm);
#endif
#ifdef HAVE_STREAMS_ROUTE
	if (ioctl(r->fd, RTSTR_SEND, rtm) < 0)
		return (-1);
#else
	if (write(r->fd, buf, rtm->rtm_msglen) < 0)
		return (-1);

	pid = getpid();
	
	while (type == RTM_GET && (len = read(r->fd, buf, sizeof(buf))) > 0) {
		if (len < (int)sizeof(*rtm)) {
			return (-1);
		}
		if (rtm->rtm_type == type && rtm->rtm_pid == pid &&
		    rtm->rtm_seq == r->seq) {
			if (rtm->rtm_errno) {
				errno = rtm->rtm_errno;
				return (-1);
			}
			break;
		}
	}
#endif
	if (type == RTM_GET && (rtm->rtm_addrs & (RTA_DST|RTA_GATEWAY)) ==
	    (RTA_DST|RTA_GATEWAY)) {
		sa = (struct sockaddr *)(rtm + 1);
		sa = NEXTSA(sa);
		
		if (addr_ston(sa, gw) < 0 || gw->addr_type != ADDR_TYPE_IP) {
			errno = ESRCH;
			return (-1);
		}
	}
	return (0);
}