Example #1
0
int
iface_Delete(struct iface *iface, struct ncp *ncp, const struct ncpaddr *del)
{
  struct ncpaddr found;
  unsigned n;
  int res, s;

  if ((s = ID0socket(ncpaddr_family(del), SOCK_DGRAM, 0)) == -1) {
    log_Printf(LogERROR, "iface_Delete: socket(): %s\n", strerror(errno));
    return 0;
  }

  for (n = res = 0; n < iface->addrs; n++) {
    ncprange_getaddr(&iface->addr[n].ifa, &found);
    if (ncpaddr_equal(&found, del)) {
      if (iface_addr_Zap(iface->name, iface->addr + n, s)) {
        ncp_IfaceAddrDeleted(ncp, iface->addr + n);
        bcopy(iface->addr + n + 1, iface->addr + n,
              (iface->addrs - n - 1) * sizeof *iface->addr);
        iface->addrs--;
        res = 1;
      }
      break;
    }
  }

  close(s);

  return res;
}
Example #2
0
void
route_Change(struct bundle *bundle, struct sticky_route *r,
             const struct ncpaddr *me, const struct ncpaddr *peer)
{
  struct ncpaddr dst;

  for (; r; r = r->next) {
    ncprange_getaddr(&r->dst, &dst);
    if (ncpaddr_family(me) == AF_INET) {
      if ((r->type & ROUTE_DSTMYADDR) && !ncpaddr_equal(&dst, me)) {
        rt_Set(bundle, RTM_DELETE, &r->dst, NULL, 1, 0);
        ncprange_sethost(&r->dst, me);
        if (r->type & ROUTE_GWHISADDR)
          ncpaddr_copy(&r->gw, peer);
      } else if ((r->type & ROUTE_DSTHISADDR) && !ncpaddr_equal(&dst, peer)) {
        rt_Set(bundle, RTM_DELETE, &r->dst, NULL, 1, 0);
        ncprange_sethost(&r->dst, peer);
        if (r->type & ROUTE_GWHISADDR)
          ncpaddr_copy(&r->gw, peer);
      } else if ((r->type & ROUTE_DSTDNS0) && !ncpaddr_equal(&dst, peer)) {
        if (bundle->ncp.ipcp.ns.dns[0].s_addr == INADDR_NONE)
          continue;
        rt_Set(bundle, RTM_DELETE, &r->dst, NULL, 1, 0);
        if (r->type & ROUTE_GWHISADDR)
          ncpaddr_copy(&r->gw, peer);
      } else if ((r->type & ROUTE_DSTDNS1) && !ncpaddr_equal(&dst, peer)) {
        if (bundle->ncp.ipcp.ns.dns[1].s_addr == INADDR_NONE)
          continue;
        rt_Set(bundle, RTM_DELETE, &r->dst, NULL, 1, 0);
        if (r->type & ROUTE_GWHISADDR)
          ncpaddr_copy(&r->gw, peer);
      } else if ((r->type & ROUTE_GWHISADDR) && !ncpaddr_equal(&r->gw, peer))
        ncpaddr_copy(&r->gw, peer);
#ifndef NOINET6
    } else if (ncpaddr_family(me) == AF_INET6) {
      if ((r->type & ROUTE_DSTMYADDR6) && !ncpaddr_equal(&dst, me)) {
        rt_Set(bundle, RTM_DELETE, &r->dst, NULL, 1, 0);
        ncprange_sethost(&r->dst, me);
        if (r->type & ROUTE_GWHISADDR)
          ncpaddr_copy(&r->gw, peer);
      } else if ((r->type & ROUTE_DSTHISADDR6) && !ncpaddr_equal(&dst, peer)) {
        rt_Set(bundle, RTM_DELETE, &r->dst, NULL, 1, 0);
        ncprange_sethost(&r->dst, peer);
        if (r->type & ROUTE_GWHISADDR)
          ncpaddr_copy(&r->gw, peer);
      } else if ((r->type & ROUTE_GWHISADDR6) && !ncpaddr_equal(&r->gw, peer))
        ncpaddr_copy(&r->gw, peer);
#endif
    }
    rt_Set(bundle, RTM_ADD, &r->dst, &r->gw, 1, 0);
  }
}
Example #3
0
const char *
ncprange_ntoa(const struct ncprange *range)
{
  char *res;
  struct ncpaddr addr;
  int len;

  if (!ncprange_getaddr(range, &addr))
    return "<AF_UNSPEC>";

  res = ncpaddr_ntowa(&addr);
  len = strlen(res);
  if (len >= NCP_ASCIIBUFFERSIZE - 1)
    return res;

  switch (range->ncprange_family) {
  case AF_INET:
    if (range->ncprange_ip4width == -1) {
      /* A non-contiguous mask */
      for (; len >= 3; res[len -= 2] = '\0')
        if (strcmp(res + len - 2, ".0"))
          break;
      snprintf(res + len, sizeof res - len, "&0x%08lx",
               (unsigned long)ntohl(range->ncprange_ip4mask.s_addr));
    } else if (range->ncprange_ip4width < 32)
      snprintf(res + len, sizeof res - len, "/%d", range->ncprange_ip4width);

    return res;

#ifndef NOINET6
  case AF_INET6:
    if (range->ncprange_ip6width != 128)
      snprintf(res + len, sizeof res - len, "/%d", range->ncprange_ip6width);

    return res;
#endif
  }

  return "<AF_UNSPEC>";
}
Example #4
0
int
iface_Show(struct cmdargs const *arg)
{
  struct ncpaddr ncpaddr;
  struct iface *iface = arg->bundle->iface, *current;
  unsigned f;
  int flags;
#ifndef NOINET6
  int scopeid, width;
#endif
  struct in_addr mask;

  current = iface_Create(iface->name);
  flags = iface->flags = current->flags;
  iface_Free(current);

  prompt_Printf(arg->prompt, "%s (idx %d) <", iface->name, iface->index);
  for (f = 0; f < sizeof if_flags / sizeof if_flags[0]; f++)
    if ((if_flags[f].flag & flags)) {
      prompt_Printf(arg->prompt, "%s%s", flags == iface->flags ? "" : ",",
                    if_flags[f].value);
      flags &= ~if_flags[f].flag;
    }

#if 0
  if (flags)
    prompt_Printf(arg->prompt, "%s0x%x", flags == iface->flags ? "" : ",",
                  flags);
#endif

  prompt_Printf(arg->prompt, "> mtu %lu has %d address%s:\n", iface->mtu,
                iface->addrs, iface->addrs == 1 ? "" : "es");

  for (f = 0; f < iface->addrs; f++) {
    ncprange_getaddr(&iface->addr[f].ifa, &ncpaddr);
    switch (ncprange_family(&iface->addr[f].ifa)) {
    case AF_INET:
      prompt_Printf(arg->prompt, "  inet %s --> ", ncpaddr_ntoa(&ncpaddr));
      if (ncpaddr_family(&iface->addr[f].peer) == AF_UNSPEC)
        prompt_Printf(arg->prompt, "255.255.255.255");
      else
        prompt_Printf(arg->prompt, "%s", ncpaddr_ntoa(&iface->addr[f].peer));
      ncprange_getip4mask(&iface->addr[f].ifa, &mask);
      prompt_Printf(arg->prompt, " netmask 0x%08lx", (long)ntohl(mask.s_addr));
      break;

#ifndef NOINET6
    case AF_INET6:
      prompt_Printf(arg->prompt, "  inet6 %s", ncpaddr_ntoa(&ncpaddr));
      if (ncpaddr_family(&iface->addr[f].peer) != AF_UNSPEC)
        prompt_Printf(arg->prompt, " --> %s",
                      ncpaddr_ntoa(&iface->addr[f].peer));
      ncprange_getwidth(&iface->addr[f].ifa, &width);
      if (ncpaddr_family(&iface->addr[f].peer) == AF_UNSPEC)
        prompt_Printf(arg->prompt, " prefixlen %d", width);
      if ((scopeid = ncprange_scopeid(&iface->addr[f].ifa)) != -1)
        prompt_Printf(arg->prompt, " scopeid 0x%x", (unsigned)scopeid);
      break;
#endif
    }
    prompt_Printf(arg->prompt, "\n");
  }

  return 0;
}
Example #5
0
int
iface_Add(struct iface *iface, struct ncp *ncp, const struct ncprange *ifa,
          const struct ncpaddr *peer, int how)
{
  int af, removed, s;
  unsigned n;
  struct ncpaddr ncplocal;
  struct iface_addr *addr, newaddr;

  af = ncprange_family(ifa);
  if ((s = ID0socket(af, SOCK_DGRAM, 0)) == -1) {
    log_Printf(LogERROR, "iface_Add: socket(): %s\n", strerror(errno));
    return 0;
  }
  ncprange_getaddr(ifa, &ncplocal);

  for (n = 0; n < iface->addrs; n++) {
    if (ncprange_contains(&iface->addr[n].ifa, &ncplocal) ||
        ncpaddr_equal(&iface->addr[n].peer, peer)) {
      /* Replace this sockaddr */
      if (!(how & IFACE_FORCE_ADD)) {
        close(s);
        return 0;	/* errno = EEXIST; */
      }

      if (ncprange_equal(&iface->addr[n].ifa, ifa) &&
          ncpaddr_equal(&iface->addr[n].peer, peer)) {
        close(s);
        ncp_IfaceAddrAdded(ncp, iface->addr + n);
        return 1;	/* Already there */
      }

      removed = iface_addr_Zap(iface->name, iface->addr + n, s);
      if (removed)
        ncp_IfaceAddrDeleted(ncp, iface->addr + n);
      ncprange_copy(&iface->addr[n].ifa, ifa);
      ncpaddr_copy(&iface->addr[n].peer, peer);
      if (!iface_addr_Add(iface->name, iface->addr + n, s)) {
        if (removed) {
          bcopy(iface->addr + n + 1, iface->addr + n,
                (iface->addrs - n - 1) * sizeof *iface->addr);
          iface->addrs--;
          n--;
        }
        close(s);
        return 0;
      }
      close(s);
      ncp_IfaceAddrAdded(ncp, iface->addr + n);
      return 1;
    }
  }

  addr = (struct iface_addr *)realloc
    (iface->addr, (iface->addrs + 1) * sizeof iface->addr[0]);
  if (addr == NULL) {
    log_Printf(LogERROR, "iface_inAdd: realloc: %s\n", strerror(errno));
    close(s);
    return 0;
  }
  iface->addr = addr;

  ncprange_copy(&newaddr.ifa, ifa);
  ncpaddr_copy(&newaddr.peer, peer);
  newaddr.system = !!(how & IFACE_SYSTEM);
  if (!iface_addr_Add(iface->name, &newaddr, s)) {
    close(s);
    return 0;
  }

  if (how & IFACE_ADD_FIRST) {
    /* Stuff it at the start of our list */
    n = 0;
    bcopy(iface->addr, iface->addr + 1, iface->addrs * sizeof *iface->addr);
  } else
    n = iface->addrs;

  iface->addrs++;
  memcpy(iface->addr + n, &newaddr, sizeof(*iface->addr));

  close(s);
  ncp_IfaceAddrAdded(ncp, iface->addr + n);

  return 1;
}