예제 #1
0
파일: arp.c 프로젝트: AhmadTux/freebsd
static int
arp_ProxySub(struct bundle *bundle, struct in_addr addr, int add)
{
  int routes;

  /*
   * Get the hardware address of an interface on the same subnet as our local
   * address.
   */

  memset(&arpmsg, 0, sizeof arpmsg);
  if (!arp_EtherAddr(addr, &arpmsg.hwa, 0)) {
    log_Printf(LogWARN, "%s: Cannot determine ethernet address for proxy ARP\n",
	       inet_ntoa(addr));
    return 0;
  }
  routes = ID0socket(PF_ROUTE, SOCK_RAW, AF_INET);
  if (routes < 0) {
    log_Printf(LogERROR, "arp_SetProxy: opening routing socket: %s\n",
	      strerror(errno));
    return 0;
  }
  arpmsg.hdr.rtm_type = add ? RTM_ADD : RTM_DELETE;
  arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC | RTF_LLDATA;
  arpmsg.hdr.rtm_version = RTM_VERSION;
  arpmsg.hdr.rtm_seq = ++bundle->routing_seq;
  arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
  arpmsg.hdr.rtm_inits = RTV_EXPIRE;
  arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp);
  arpmsg.dst.sin_family = AF_INET;
  arpmsg.dst.sin_addr.s_addr = addr.s_addr;
  arpmsg.dst.sin_other = SIN_PROXY;

  arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg
    + arpmsg.hwa.sdl_len;


  if (ID0write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0 &&
      !(!add && errno == ESRCH)) {
    log_Printf(LogERROR, "%s proxy arp entry %s: %s\n",
	add ? "Add" : "Delete", inet_ntoa(addr), strerror(errno));
    close(routes);
    return 0;
  }
  close(routes);
  return 1;
}
예제 #2
0
파일: route.c 프로젝트: Gwenio/DragonFlyBSD
void
rt_Update(struct bundle *bundle, const struct sockaddr *dst,
          const struct sockaddr *gw, const struct sockaddr *mask)
{
  struct ncprange ncpdst;
  struct rtmsg rtmes;
  char *p;
  int s, wb;

  s = ID0socket(PF_ROUTE, SOCK_RAW, 0);
  if (s < 0) {
    log_Printf(LogERROR, "rt_Update: socket(): %s\n", strerror(errno));
    return;
  }

  memset(&rtmes, '\0', sizeof rtmes);
  rtmes.m_rtm.rtm_version = RTM_VERSION;
  rtmes.m_rtm.rtm_type = RTM_CHANGE;
  rtmes.m_rtm.rtm_addrs = 0;
  rtmes.m_rtm.rtm_seq = ++bundle->routing_seq;
  rtmes.m_rtm.rtm_pid = getpid();
  rtmes.m_rtm.rtm_flags = RTF_UP | RTF_STATIC;

  if (bundle->ncp.cfg.sendpipe > 0) {
    rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.cfg.sendpipe;
    rtmes.m_rtm.rtm_inits |= RTV_SPIPE;
  }

  if (bundle->ncp.cfg.recvpipe > 0) {
    rtmes.m_rtm.rtm_rmx.rmx_recvpipe = bundle->ncp.cfg.recvpipe;
    rtmes.m_rtm.rtm_inits |= RTV_RPIPE;
  }

  rtmes.m_rtm.rtm_rmx.rmx_mtu = bundle->iface->mtu;
  rtmes.m_rtm.rtm_inits |= RTV_MTU;
  p = rtmes.m_space;

  if (dst) {
    rtmes.m_rtm.rtm_addrs |= RTA_DST;
    p += memcpy_roundup(p, dst, dst->sa_len);
  }

  rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
  p += memcpy_roundup(p, gw, gw->sa_len);
  if (mask) {
    rtmes.m_rtm.rtm_addrs |= RTA_NETMASK;
    p += memcpy_roundup(p, mask, mask->sa_len);
  }

  rtmes.m_rtm.rtm_msglen = p - (char *)&rtmes;

  wb = ID0write(s, &rtmes, rtmes.m_rtm.rtm_msglen);
  if (wb < 0) {
    ncprange_setsa(&ncpdst, dst, mask);

    log_Printf(LogTCPIP, "rt_Update failure:\n");
    log_Printf(LogTCPIP, "rt_Update:  Dst = %s\n", ncprange_ntoa(&ncpdst));

    if (rtmes.m_rtm.rtm_errno == 0)
      log_Printf(LogWARN, "%s: Change route failed: errno: %s\n",
                 ncprange_ntoa(&ncpdst), strerror(errno));
    else
      log_Printf(LogWARN, "%s: Change route failed: %s\n",
		 ncprange_ntoa(&ncpdst), strerror(rtmes.m_rtm.rtm_errno));
  }
  close(s);
}
예제 #3
0
파일: route.c 프로젝트: Gwenio/DragonFlyBSD
int
rt_Set(struct bundle *bundle, int cmd, const struct ncprange *dst,
       const struct ncpaddr *gw, int bang, int quiet)
{
  struct rtmsg rtmes;
  int s, nb, wb;
  char *cp;
  const char *cmdstr;
  struct sockaddr_storage sadst, samask, sagw;
  int result = 1;

  if (bang)
    cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!");
  else
    cmdstr = (cmd == RTM_ADD ? "Add" : "Delete");
  s = ID0socket(PF_ROUTE, SOCK_RAW, 0);
  if (s < 0) {
    log_Printf(LogERROR, "rt_Set: socket(): %s\n", strerror(errno));
    return result;
  }
  memset(&rtmes, '\0', sizeof rtmes);
  rtmes.m_rtm.rtm_version = RTM_VERSION;
  rtmes.m_rtm.rtm_type = cmd;
  rtmes.m_rtm.rtm_addrs = RTA_DST;
  rtmes.m_rtm.rtm_seq = ++bundle->routing_seq;
  rtmes.m_rtm.rtm_pid = getpid();
  rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;

  if (cmd == RTM_ADD) {
    if (bundle->ncp.cfg.sendpipe > 0) {
      rtmes.m_rtm.rtm_rmx.rmx_sendpipe = bundle->ncp.cfg.sendpipe;
      rtmes.m_rtm.rtm_inits |= RTV_SPIPE;
    }
    if (bundle->ncp.cfg.recvpipe > 0) {
      rtmes.m_rtm.rtm_rmx.rmx_recvpipe = bundle->ncp.cfg.recvpipe;
      rtmes.m_rtm.rtm_inits |= RTV_RPIPE;
    }
  }

  ncprange_getsa(dst, &sadst, &samask);
#if defined(__KAME__) && !defined(NOINET6)
  add_scope((struct sockaddr *)&sadst, bundle->iface->index);
#endif

  cp = rtmes.m_space;
  cp += memcpy_roundup(cp, &sadst, sadst.ss_len);
  if (cmd == RTM_ADD) {
    if (gw == NULL) {
      log_Printf(LogERROR, "rt_Set: Program error\n");
      close(s);
      return result;
    }
    ncpaddr_getsa(gw, &sagw);
#if defined(__KAME__) && !defined(NOINET6)
    add_scope((struct sockaddr *)&sagw, bundle->iface->index);
#endif
    if (ncpaddr_isdefault(gw)) {
      if (!quiet)
        log_Printf(LogERROR, "rt_Set: Cannot add a route with"
                   " gateway 0.0.0.0\n");
      close(s);
      return result;
    } else {
      cp += memcpy_roundup(cp, &sagw, sagw.ss_len);
      rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
    }
  }

  if (!ncprange_ishost(dst)) {
    cp += memcpy_roundup(cp, &samask, samask.ss_len);
    rtmes.m_rtm.rtm_addrs |= RTA_NETMASK;
  }

  nb = cp - (char *)&rtmes;
  rtmes.m_rtm.rtm_msglen = nb;
  wb = ID0write(s, &rtmes, nb);
  if (wb < 0) {
    log_Printf(LogTCPIP, "rt_Set failure:\n");
    log_Printf(LogTCPIP, "rt_Set:  Cmd = %s\n", cmdstr);
    log_Printf(LogTCPIP, "rt_Set:  Dst = %s\n", ncprange_ntoa(dst));
    if (gw != NULL)
      log_Printf(LogTCPIP, "rt_Set:  Gateway = %s\n", ncpaddr_ntoa(gw));
failed:
    if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST ||
                           (rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) {
      if (!bang) {
        log_Printf(LogWARN, "Add route failed: %s already exists\n",
		   ncprange_ntoa(dst));
        result = 0;	/* Don't add to our dynamic list */
      } else {
        rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE;
        if ((wb = ID0write(s, &rtmes, nb)) < 0)
          goto failed;
      }
    } else if (cmd == RTM_DELETE &&
             (rtmes.m_rtm.rtm_errno == ESRCH ||
              (rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) {
      if (!bang)
        log_Printf(LogWARN, "Del route failed: %s: Non-existent\n",
                  ncprange_ntoa(dst));
    } else if (rtmes.m_rtm.rtm_errno == 0) {
      if (!quiet || errno != ENETUNREACH)
        log_Printf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr,
                   ncprange_ntoa(dst), strerror(errno));
    } else
      log_Printf(LogWARN, "%s route failed: %s: %s\n",
		 cmdstr, ncprange_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno));
  }

  if (log_IsKept(LogDEBUG)) {
    char gwstr[40];

    if (gw)
      snprintf(gwstr, sizeof gwstr, "%s", ncpaddr_ntoa(gw));
    else
      snprintf(gwstr, sizeof gwstr, "<none>");
    log_Printf(LogDEBUG, "wrote %d: cmd = %s, dst = %s, gateway = %s\n",
               wb, cmdstr, ncprange_ntoa(dst), gwstr);
  }
  close(s);

  return result;
}