Exemplo n.º 1
0
static int do_address(const char *ifname,
                      struct in_addr address, struct in_addr netmask,
                      struct in_addr broadcast, int del)
{
    struct
    {
        struct nlmsghdr hdr;
        struct ifaddrmsg ifa;
        char buffer[64];
    }
    nlm;

    if (!ifname)
        return -1;

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

    nlm.hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
    nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
    if (! del)
        nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
    nlm.hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
    nlm.ifa.ifa_index = if_nametoindex (ifname);
    nlm.ifa.ifa_family = AF_INET;

    nlm.ifa.ifa_prefixlen = inet_ntocidr (netmask);
    add_attr_l (&nlm.hdr, sizeof (nlm), IFA_LOCAL, &address.s_addr,
                sizeof (address.s_addr));
    if (! del)
        add_attr_l (&nlm.hdr, sizeof (nlm), IFA_BROADCAST, &broadcast.s_addr,
                    sizeof (broadcast.s_addr));

    return send_netlink (&nlm.hdr);
}
Exemplo n.º 2
0
int
if_address(const struct interface *iface,
    const struct in_addr *address, const struct in_addr *netmask,
    const struct in_addr *broadcast, int action)
{
	struct nlma *nlm;
	int retval = 0;

	nlm = calloc(1, sizeof(*nlm));
	if (nlm == NULL)
		return -1;
	nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
	nlm->hdr.nlmsg_flags = NLM_F_REQUEST;
	if (action >= 0) {
		nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
		nlm->hdr.nlmsg_type = RTM_NEWADDR;
	} else
		nlm->hdr.nlmsg_type = RTM_DELADDR;
	nlm->ifa.ifa_index = iface->index;
	nlm->ifa.ifa_family = AF_INET;
	nlm->ifa.ifa_prefixlen = inet_ntocidr(*netmask);
	/* This creates the aliased interface */
	add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_LABEL,
	    iface->name, strlen(iface->name) + 1);
	add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_LOCAL,
	    &address->s_addr, sizeof(address->s_addr));
	if (action >= 0 && broadcast)
		add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_BROADCAST,
		    &broadcast->s_addr, sizeof(broadcast->s_addr));

	if (send_netlink(&nlm->hdr) == -1)
		retval = -1;
	free(nlm);
	return retval;
}
Exemplo n.º 3
0
static int do_address(const char *ifname,
					  struct in_addr address, struct in_addr netmask,
					  struct in_addr broadcast, int del)
{
	struct nlma *nlm;
	int retval;

	if (!ifname)
		return -1;

	nlm = xmalloc (sizeof (struct nlma));
	memset (nlm, 0, sizeof (struct nlma));

	nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
	nlm->hdr.nlmsg_flags = NLM_F_REQUEST;
	if (! del)
		nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
	nlm->hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
	if (! (nlm->ifa.ifa_index = if_nametoindex (ifname))) {
		logger (LOG_ERR, "if_nametoindex: Couldn't find index for interface `%s'",
				ifname);
		free (nlm);
		return -1;
	}
	nlm->ifa.ifa_family = AF_INET;

	nlm->ifa.ifa_prefixlen = inet_ntocidr (netmask);

	/* This creates the aliased interface */
	add_attr_l (&nlm->hdr, sizeof (struct nlma), IFA_LABEL,
				ifname, strlen (ifname) + 1);

	add_attr_l (&nlm->hdr, sizeof (struct nlma), IFA_LOCAL,
				&address.s_addr, sizeof (address.s_addr));
	if (! del)
		add_attr_l (&nlm->hdr, sizeof (struct nlma), IFA_BROADCAST,
					&broadcast.s_addr, sizeof (broadcast.s_addr));

	retval = send_netlink (&nlm->hdr);
	free (nlm);
	return retval;
}
Exemplo n.º 4
0
static int do_address(const char *ifname,
		      struct in_addr address, struct in_addr netmask,
		      struct in_addr broadcast, int del)
{
  if (!ifname)
    return -1;

  struct
    {
      struct nlmsghdr hdr;
      struct ifaddrmsg ifa;
      char buffer[256];
    }
  nlm;

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

  nlm.hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
  nlm.hdr.nlmsg_flags = NLM_F_REQUEST;
  nlm.hdr.nlmsg_type = del ? RTM_DELADDR : RTM_NEWADDR;
  nlm.ifa.ifa_index = if_nametoindex (ifname);
  nlm.ifa.ifa_family = AF_INET;

  /* Store the netmask in the prefix */
  uint32_t mask = htonl (netmask.s_addr);
  while (mask)
    {
      nlm.ifa.ifa_prefixlen++;
      mask <<= 1;
    }

  add_attr_l (&nlm.hdr, sizeof (nlm), IFA_LOCAL, &address.s_addr,
	      sizeof (address.s_addr));
  if (! del)
    add_attr_l (&nlm.hdr, sizeof (nlm), IFA_BROADCAST, &broadcast.s_addr,
		sizeof (broadcast.s_addr));

  return send_netlink (&nlm.hdr);
}
Exemplo n.º 5
0
int
if_address6(const struct ipv6_addr *ap, int action)
{
	struct nlma *nlm;
	struct ifa_cacheinfo cinfo;
	int retval = 0;

	nlm = calloc(1, sizeof(*nlm));
	if (nlm == NULL)
		return -1;
	nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
	nlm->hdr.nlmsg_flags = NLM_F_REQUEST;
	if (action >= 0) {
		nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
		nlm->hdr.nlmsg_type = RTM_NEWADDR;
	} else
		nlm->hdr.nlmsg_type = RTM_DELADDR;
	nlm->ifa.ifa_index = ap->iface->index;
	nlm->ifa.ifa_family = AF_INET6;
	nlm->ifa.ifa_prefixlen = ap->prefix_len;
	/* This creates the aliased interface */
	add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_LABEL,
	    ap->iface->name, strlen(ap->iface->name) + 1);
	add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_LOCAL,
	    &ap->addr.s6_addr, sizeof(ap->addr.s6_addr));

	if (action >= 0) {
		memset(&cinfo, 0, sizeof(cinfo));
		cinfo.ifa_prefered = ap->prefix_pltime;
		cinfo.ifa_valid = ap->prefix_vltime;
		add_attr_l(&nlm->hdr, sizeof(*nlm), IFA_CACHEINFO,
		    &cinfo, sizeof(cinfo));
	}

	if (send_netlink(&nlm->hdr) == -1)
		retval = -1;
	free(nlm);
	return retval;
}
int
if_route(const char *ifname,
	 const struct in_addr *destination, const struct in_addr *netmask,
	 const struct in_addr *gateway, int metric, int action)
{
	struct nlmr *nlm;
	unsigned int ifindex;
	int retval = 0;


	if (!(ifindex = if_nametoindex(ifname))) {
		errno = ENODEV;
		return -1;
	}

	nlm = xzalloc(sizeof(*nlm));
	nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	nlm->hdr.nlmsg_type = RTM_NEWROUTE;
	if (action == 0)
            nlm->hdr.nlmsg_flags = NLM_F_REPLACE;
	else if (action > 0)
		/*
		 * ers@google:
		 * commented out NLM_F_EXCL here and below. We
		 * sometimes keep one interface up while we are
		 * configuring the other one, and this flag
		 * causes route addition to fail.
		 */
		nlm->hdr.nlmsg_flags = NLM_F_CREATE /* | NLM_F_EXCL */;
	else
		nlm->hdr.nlmsg_type = RTM_DELROUTE;
	nlm->hdr.nlmsg_flags |= NLM_F_REQUEST;
	nlm->rt.rtm_family = AF_INET;
	nlm->rt.rtm_table = RT_TABLE_MAIN;

	if (action < 0)
		nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
	else {
		nlm->hdr.nlmsg_flags |= NLM_F_CREATE /*| NLM_F_EXCL*/;
		nlm->rt.rtm_protocol = RTPROT_BOOT;
		if (gateway->s_addr == INADDR_ANY)
			nlm->rt.rtm_scope = RT_SCOPE_LINK;
		else
			nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE;
		nlm->rt.rtm_type = RTN_UNICAST;
	}

	nlm->rt.rtm_dst_len = inet_ntocidr(*netmask);
	add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_DST,
		   &destination->s_addr, sizeof(destination->s_addr));
	add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_GATEWAY,
		   &gateway->s_addr, sizeof(gateway->s_addr));

	add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, ifindex);
	add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, metric);

	if (send_netlink(&nlm->hdr) == -1)
		retval = -1;
	free(nlm);
	return retval;
}
Exemplo n.º 7
0
static int do_route (const char *ifname,
                     struct in_addr destination,
                     struct in_addr netmask,
                     struct in_addr gateway,
                     int metric, int change, int del)
{
    char *dstd;
    char *gend;
    struct
    {
        struct nlmsghdr hdr;
        struct rtmsg rt;
        char buffer[256];
    }
    nlm;

    if (! ifname)
        return -1;

    dstd = strdup (inet_ntoa (destination));
    gend = strdup (inet_ntoa (netmask));
    if (gateway.s_addr == destination.s_addr)
        logger (LOG_INFO, "%s route to %s (%s) metric %d",
                change ? "changing" : del ? "removing" : "adding",
                dstd, gend, metric);
    else if (destination.s_addr == INADDR_ANY && netmask.s_addr == INADDR_ANY)
        logger (LOG_INFO, "%s default route via %s metric %d",
                change ? "changing" : del ? "removing" : "adding",
                inet_ntoa (gateway), metric);
    else
        logger (LOG_INFO, "%s route to %s (%s) via %s metric %d",
                change ? "changing" : del ? "removing" : "adding",
                dstd, gend, inet_ntoa (gateway), metric);
    if (dstd)
        free (dstd);
    if (gend)
        free (gend);

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

    nlm.hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
    if (change)
        nlm.hdr.nlmsg_flags = NLM_F_REPLACE;
    else if (! del)
        nlm.hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
    nlm.hdr.nlmsg_flags |= NLM_F_REQUEST;
    nlm.hdr.nlmsg_type = del ? RTM_DELROUTE : RTM_NEWROUTE;
    nlm.rt.rtm_family = AF_INET;
    nlm.rt.rtm_table = RT_TABLE_MAIN;

    if (del)
        nlm.rt.rtm_scope = RT_SCOPE_NOWHERE;
    else
    {
        nlm.hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
        nlm.rt.rtm_protocol = RTPROT_BOOT;
        if (gateway.s_addr == INADDR_ANY ||
                netmask.s_addr == INADDR_BROADCAST)
            nlm.rt.rtm_scope = RT_SCOPE_LINK;
        else
            nlm.rt.rtm_scope = RT_SCOPE_UNIVERSE;
        nlm.rt.rtm_type = RTN_UNICAST;
    }

    nlm.rt.rtm_dst_len = inet_ntocidr (netmask);
    add_attr_l (&nlm.hdr, sizeof (nlm), RTA_DST, &destination.s_addr,
                sizeof (destination.s_addr));
    if (gateway.s_addr != INADDR_ANY && gateway.s_addr != destination.s_addr)
        add_attr_l (&nlm.hdr, sizeof (nlm), RTA_GATEWAY, &gateway.s_addr,
                    sizeof (gateway.s_addr));

    add_attr_32 (&nlm.hdr, sizeof (nlm), RTA_OIF, if_nametoindex (ifname));
    add_attr_32 (&nlm.hdr, sizeof (nlm), RTA_PRIORITY, metric);

    return send_netlink (&nlm.hdr);
}
Exemplo n.º 8
0
static int do_route (const char *ifname,
					 struct in_addr destination,
					 struct in_addr netmask,
					 struct in_addr gateway,
					 int metric, int change, int del)
{
	struct nlmr *nlm;
	unsigned int ifindex;
	int retval;

	if (! ifname)
		return -1;

	log_route (destination, netmask, gateway, metric, change, del);

	if (! (ifindex = if_nametoindex (ifname))) {
		logger (LOG_ERR, "if_nametoindex: Couldn't find index for interface `%s'",
				ifname);
		return -1;
	}

	nlm = xmalloc (sizeof (struct nlmr));
	memset (nlm, 0, sizeof (struct nlmr));

	nlm->hdr.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
	if (change)
		nlm->hdr.nlmsg_flags = NLM_F_REPLACE;
	else if (! del)
		nlm->hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
	nlm->hdr.nlmsg_flags |= NLM_F_REQUEST;
	nlm->hdr.nlmsg_type = del ? RTM_DELROUTE : RTM_NEWROUTE;
	nlm->rt.rtm_family = AF_INET;
	nlm->rt.rtm_table = RT_TABLE_MAIN;

	if (del)
		nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
	else {
		nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
		nlm->rt.rtm_protocol = RTPROT_BOOT;
		if (netmask.s_addr == INADDR_BROADCAST ||
			gateway.s_addr == INADDR_ANY)
			nlm->rt.rtm_scope = RT_SCOPE_LINK;
		else
			nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE;
		nlm->rt.rtm_type = RTN_UNICAST;
	}

	nlm->rt.rtm_dst_len = inet_ntocidr (netmask);
	add_attr_l (&nlm->hdr, sizeof (struct nlmr), RTA_DST,
				&destination.s_addr, sizeof (destination.s_addr));
	if (netmask.s_addr != INADDR_BROADCAST &&
		destination.s_addr != gateway.s_addr)
		add_attr_l (&nlm->hdr, sizeof (struct nlmr), RTA_GATEWAY,
					&gateway.s_addr, sizeof (gateway.s_addr));

	add_attr_32 (&nlm->hdr, sizeof (struct nlmr), RTA_OIF, ifindex);
	add_attr_32 (&nlm->hdr, sizeof (struct nlmr), RTA_PRIORITY, metric);

	retval = send_netlink (&nlm->hdr);
	free (nlm);
	return retval;
}
Exemplo n.º 9
0
int
if_route6(const struct rt6 *rt, int action)
{
	struct nlmr *nlm;
	char metricsbuf[32];
	struct rtattr *metrics = (void *)metricsbuf;
	int retval = 0;

	nlm = calloc(1, sizeof(*nlm));
	if (nlm == NULL)
		return -1;
	nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	nlm->hdr.nlmsg_type = RTM_NEWROUTE;
	nlm->hdr.nlmsg_flags = NLM_F_REQUEST;
	if (action == 0)
		nlm->hdr.nlmsg_flags |= NLM_F_REPLACE;
	else if (action == 1)
		nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
	else
		nlm->hdr.nlmsg_type = RTM_DELROUTE;
	nlm->rt.rtm_family = AF_INET6;
	nlm->rt.rtm_table = RT_TABLE_MAIN;

	if (action == -1 || action == -2)
		nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
	else {
		nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
		/* None interface subnet routes are static. */
		if (IN6_IS_ADDR_UNSPECIFIED(&rt->gate)) {
			nlm->rt.rtm_protocol = RTPROT_KERNEL;
			nlm->rt.rtm_scope = RT_SCOPE_LINK;
		} else
			nlm->rt.rtm_protocol = RTPROT_BOOT;
		nlm->rt.rtm_type = RTN_UNICAST;
	}

	nlm->rt.rtm_dst_len = ipv6_prefixlen(&rt->net);
	add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_DST,
	    &rt->dest.s6_addr, sizeof(rt->dest.s6_addr));

	/* If destination == gateway then don't add the gateway */
	if (!IN6_IS_ADDR_UNSPECIFIED(&rt->gate) &&
	    !IN6_ARE_ADDR_EQUAL(&rt->dest, &rt->gate))
		add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_GATEWAY,
		    &rt->gate.s6_addr, sizeof(rt->gate.s6_addr));

	add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, rt->iface->index);
	add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, rt->metric);

	if (rt->mtu) {
		metrics->rta_type = RTA_METRICS;
		metrics->rta_len = RTA_LENGTH(0);
		rta_add_attr_32(metrics, sizeof(metricsbuf), RTAX_MTU, rt->mtu);
		add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_METRICS,
		    RTA_DATA(metrics), RTA_PAYLOAD(metrics));
	}

	if (send_netlink(&nlm->hdr) == -1)
		retval = -1;
	free(nlm);
	return retval;
	errno = ENOTSUP;
	return -1;
}
Exemplo n.º 10
0
int
if_route(const struct rt *rt, int action)
{
	struct nlmr *nlm;
	int retval = 0;
	struct dhcp_state *state;

	nlm = calloc(1, sizeof(*nlm));
	if (nlm == NULL)
		return -1;
	nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	nlm->hdr.nlmsg_type = RTM_NEWROUTE;
	if (action == 0)
		nlm->hdr.nlmsg_flags = NLM_F_REPLACE;
	else if (action == 1)
		nlm->hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL;
	else
		nlm->hdr.nlmsg_type = RTM_DELROUTE;
	nlm->hdr.nlmsg_flags |= NLM_F_REQUEST;
	nlm->rt.rtm_family = AF_INET;
	nlm->rt.rtm_table = RT_TABLE_MAIN;

	state = D_STATE(rt->iface);
	if (action == -1 || action == -2)
		nlm->rt.rtm_scope = RT_SCOPE_NOWHERE;
	else {
		nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
		/* We only change route metrics for kernel routes */
		if (rt->dest.s_addr ==
		    (state->addr.s_addr & state->net.s_addr) &&
		    rt->net.s_addr == state->net.s_addr)
			nlm->rt.rtm_protocol = RTPROT_KERNEL;
		else
			nlm->rt.rtm_protocol = RTPROT_BOOT;
		if (rt->gate.s_addr == INADDR_ANY ||
		    (rt->gate.s_addr == rt->dest.s_addr &&
			rt->net.s_addr == INADDR_BROADCAST))
			nlm->rt.rtm_scope = RT_SCOPE_LINK;
		else
			nlm->rt.rtm_scope = RT_SCOPE_UNIVERSE;
		nlm->rt.rtm_type = RTN_UNICAST;
	}

	nlm->rt.rtm_dst_len = inet_ntocidr(rt->net);
	add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_DST,
	    &rt->dest.s_addr, sizeof(rt->dest.s_addr));
	if (nlm->rt.rtm_protocol == RTPROT_KERNEL) {
		add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_PREFSRC,
		    &state->addr.s_addr, sizeof(state->addr.s_addr));
	}
	/* If destination == gateway then don't add the gateway */
	if (rt->dest.s_addr != rt->gate.s_addr ||
	    rt->net.s_addr != INADDR_BROADCAST)
		add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_GATEWAY,
		    &rt->gate.s_addr, sizeof(rt->gate.s_addr));

	if (rt->gate.s_addr != htonl(INADDR_LOOPBACK))
		add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_OIF, rt->iface->index);
	add_attr_32(&nlm->hdr, sizeof(*nlm), RTA_PRIORITY, rt->metric);

	if (send_netlink(&nlm->hdr) == -1)
		retval = -1;
	free(nlm);
	return retval;
}