コード例 #1
0
/*
* Delete any previous route for an old address.
*/
static void
ipx_ifscrub(struct ifnet *ifp, struct ipx_ifaddr *ia)
{
	if (ia->ia_flags & IFA_ROUTE) {
		if (ifp->if_flags & IFF_POINTOPOINT) {
			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
		} else
			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
		ia->ia_flags &= ~IFA_ROUTE;
	}
}
コード例 #2
0
/*
 * Initialize an interface's internet address
 * and routing table entry.
 */
static int
ipx_ifinit(struct ifnet *ifp, struct ipx_ifaddr *ia,
	   struct sockaddr_ipx *sipx, int scrub)
{
	struct sockaddr_ipx oldaddr;
	int error;

	/*
	 * Set up new addresses.
	 */
	oldaddr = ia->ia_addr;
	ia->ia_addr = *sipx;

	/*
	 * The convention we shall adopt for naming is that
	 * a supplied address of zero means that "we don't care".
	 * Use the MAC address of the interface. If it is an
	 * interface without a MAC address, like a serial line, the
	 * address must be supplied.
	 *
	 * Give the interface a chance to initialize
	 * if this is its first address,
	 * and to validate the address if necessary.
	 */
	ifnet_serialize_all(ifp);
	if (ifp->if_ioctl != NULL &&
	    (error = ifp->if_ioctl(ifp, SIOCSIFADDR, (void *)ia, NULL))) {
		ia->ia_addr = oldaddr;
		ifnet_deserialize_all(ifp);
		return (error);
	}
	ifnet_deserialize_all(ifp);
	ia->ia_ifa.ifa_metric = ifp->if_metric;
	/*
	 * Add route for the network.
	 */
	if (scrub) {
		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
		ipx_ifscrub(ifp, ia);
		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
	}
	if (ifp->if_flags & IFF_POINTOPOINT)
		rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
	else {
		ia->ia_broadaddr.sipx_addr.x_net = ia->ia_addr.sipx_addr.x_net;
		rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_UP);
	}
	ia->ia_flags |= IFA_ROUTE;
	return (0);
}
コード例 #3
0
/*------------------------------------------------------------------------
 *  rtget  -  get the route for a given IP destination
 *------------------------------------------------------------------------
 */
struct route *
rtget(IPaddr dest, Bool local)
{
	struct	route	*prt;
	int		hv;

	if (!Route.ri_valid)
		rtinit();
	wait(Route.ri_mutex);
	hv = rthash(dest);
	for (prt=rttable[hv]; prt; prt=prt->rt_next) {
		if (prt->rt_ttl <= 0)
			continue;		/* route has expired */
		if (netmatch(dest, prt->rt_net, prt->rt_mask, local))
			if (prt->rt_metric < RTM_INF)
				break;
	}
	if (prt == 0)
		prt = Route.ri_default;	/* may be NULL too... */
	if (prt != 0 && prt->rt_metric >= RTM_INF)
		prt = 0;
	if (prt) {
		prt->rt_refcnt++;
		prt->rt_usecnt++;
	}
	signal(Route.ri_mutex);
	return prt;
}
コード例 #4
0
/*
 * Given an interface and an at_ifaddr (supposedly on that interface)
 * remove  any routes that depend on this.
 * Why ifp is needed I'm not sure,
 * as aa->at_ifaddr.ifa_ifp should be the same.
 */
static int
at_scrub(struct ifnet *ifp, struct at_ifaddr *aa)
{
    int			error;

    if ( aa->aa_flags & AFA_ROUTE ) {
        if (ifp->if_flags & IFF_LOOPBACK) {
            if ((error = aa_delsingleroute(&aa->aa_ifa,
                                           &aa->aa_addr.sat_addr,
                                           &aa->aa_netmask.sat_addr)) != 0) {
                return( error );
            }
        } else if (ifp->if_flags & IFF_POINTOPOINT) {
            if ((error = rtinit( &aa->aa_ifa, RTM_DELETE, RTF_HOST)) != 0)
                return( error );
        } else if (ifp->if_flags & IFF_BROADCAST) {
            error = aa_dorangeroute(&aa->aa_ifa,
                                    ntohs(aa->aa_firstnet),
                                    ntohs(aa->aa_lastnet),
                                    RTM_DELETE );
        }
        aa->aa_ifa.ifa_flags &= ~IFA_ROUTE;
        aa->aa_flags &= ~AFA_ROUTE;
    }
    return( 0 );
}
コード例 #5
0
ファイル: inLib.c プロジェクト: phoboz/vmx
void in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia)
{
  /* If no route */
  if ( (ia->ia_flags & IFA_ROUTE) == 0)
    return;

  if (ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT) )
    rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST);
  else
    rtinit(&ia->ia_ifa, RTM_DELETE, 0);

  ia->ia_flags &= ~IFA_ROUTE;

#if 0
  ifa_rtcleanup(&ia->ia_ifa);
#endif
}
コード例 #6
0
ファイル: main.c プロジェクト: appleorange1/asus-rt-n12-lx
int cfg_proc(void)
{
unsigned int	i;
char argv[MAX_ARGS][MAX_ARG_LEN+1];
int	argc = 0;
int arg_idx = 0;

	for(i=0; ch_buf[i]!='\0'; i++)
	{
		if(ch_buf[i]==' '){
			argv[argc][arg_idx]='\0';
			argc++;
			arg_idx=0;
		}
		else {
			if(arg_idx<MAX_ARG_LEN)
			{	
				argv[argc][arg_idx]=ch_buf[i];
				arg_idx++;
			}
		}
	}
	argv[argc][arg_idx]='\0';
	//printf("cfg file arg[0]=%s\n",argv[0]);
	if(!strcmp(argv[0], "version")) {
		int new_ripversion = atoi(argv[1]);
		if(ripversion!=new_ripversion) {
			if(ripversion && new_ripversion == 0){				
				clean();
			}
			if(ripversion==0 && new_ripversion) {
				rtinit();
				ifinit();
				rip_input_init();
				rip_request_send();
			}
			ripversion = new_ripversion;
		}		
	}
	else
	if(!strcmp(argv[0], "network")) {
		// Modified by Mason Yu for bind interface
		//if_chk_add(argv[1]);
#ifndef CONFIG_BOA_WEB_E8B_CH
		if_chk_add(argv[1], atoi(argv[2]), atoi(argv[3]));
#else
		if_chk_add(argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
#endif
	}
	else
	if(!strcmp(argv[0], "debug")) {
		debug = 1;
	}

	memset(argv, 0, sizeof(argv));
	return 0;
}
コード例 #7
0
/*
 * tunclose - close the device - mark i/f down & delete
 * routing info
 */
int
tunclose(dev_t dev, int flag, int mode,
    struct lwp *l)
{
	int	s;
	struct tun_softc *tp;
	struct ifnet	*ifp;

	s = splnet();
	if ((tp = tun_find_zunit(minor(dev))) != NULL) {
		/* interface was "destroyed" before the close */
		seldestroy(&tp->tun_rsel);
		seldestroy(&tp->tun_wsel);
		softint_disestablish(tp->tun_osih);
		softint_disestablish(tp->tun_isih);
		mutex_destroy(&tp->tun_lock);
		free(tp, M_DEVBUF);
		goto out_nolock;
	}

	if ((tp = tun_find_unit(dev)) == NULL)
		goto out_nolock;

	ifp = &tp->tun_if;

	tp->tun_flags &= ~TUN_OPEN;

	tp->tun_pgid = 0;
	selnotify(&tp->tun_rsel, 0, 0);

	TUNDEBUG ("%s: closed\n", ifp->if_xname);
	mutex_exit(&tp->tun_lock);

	/*
	 * junk all pending output
	 */
	IFQ_PURGE(&ifp->if_snd);

	if (ifp->if_flags & IFF_UP) {
		if_down(ifp);
		if (ifp->if_flags & IFF_RUNNING) {
			/* find internet addresses and delete routes */
			struct ifaddr *ifa;
			IFADDR_FOREACH(ifa, ifp) {
#if defined(INET) || defined(INET6)
				if (ifa->ifa_addr->sa_family == AF_INET ||
				    ifa->ifa_addr->sa_family == AF_INET6) {
					rtinit(ifa, (int)RTM_DELETE,
					       tp->tun_flags & TUN_DSTADDR
							? RTF_HOST
							: 0);
				}
#endif
			}
		}
	}
コード例 #8
0
ファイル: if_tun.c プロジェクト: MarginC/kame
/*
 * tunclose - close the device - mark i/f down & delete
 * routing info
 */
static	int
tunclose(struct cdev *dev, int foo, int bar, struct thread *td)
{
	struct tun_softc *tp;
	struct ifnet *ifp;
	int s;

	tp = dev->si_drv1;
	ifp = &tp->tun_if;

	mtx_lock(&tp->tun_mtx);
	tp->tun_flags &= ~TUN_OPEN;
	tp->tun_pid = 0;

	/*
	 * junk all pending output
	 */
	s = splimp();
	IFQ_PURGE(&ifp->if_snd);
	splx(s);
	mtx_unlock(&tp->tun_mtx);

	if (ifp->if_flags & IFF_UP) {
		s = splimp();
		if_down(ifp);
		splx(s);
	}

	if (ifp->if_flags & IFF_RUNNING) {
		struct ifaddr *ifa;

		s = splimp();
		/* find internet addresses and delete routes */
		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
			if (ifa->ifa_addr->sa_family == AF_INET)
				/* Unlocked read. */
				rtinit(ifa, (int)RTM_DELETE,
				    tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
		ifp->if_flags &= ~IFF_RUNNING;
		splx(s);
	}

	funsetown(&tp->tun_sigio);
	selwakeuppri(&tp->tun_rsel, PZERO + 1);
	TUNDEBUG (ifp, "closed\n");
	return (0);
}
コード例 #9
0
ファイル: ripd.c プロジェクト: carriercomm/myboxfs
int
ripd(int argc, char *argv[])
{
	int n, nfd, tflags = 0, ch;
	struct timeval *tvp, waittime;
	struct itimerval itval;
	struct rip *query = msg;
	fd_set ibits;
	sigset_t sigset, osigset;
	
	while ((ch = getopt(argc, argv, "sqtdg")) != EOF) {
		switch (ch) {
			case 's': supplier = 1; break;
			case 'q': supplier = 0; break;
			case 't': 
				tflags++;
				break;
			case 'd': 
				debug++;
				setlogmask(LOG_UPTO(LOG_DEBUG));
				break;
			case 'g': gateway = 1; break;
			default:
				fprintf(stderr, "%% Incomplete command\r\n");
				return(1);
		}
	}

	getkversion();

	sock = getsocket();
	assert(sock>=0);

	openlog("ripd", LOG_PID | LOG_ODELAY, LOG_DAEMON);

	if (debug == 0 && tflags == 0) {
		switch (fork()) {
			case -1: perror("fork"); exit(1);
			case 0: break;   /* child */
			default: exit(0);  /* parent */
		}
		close(0);
		close(1);
		close(2);
		setsid();
		setlogmask(LOG_UPTO(LOG_WARNING));
	}
	else {
		setlogmask(LOG_UPTO(LOG_DEBUG));
	}
	/* pid */	
	pidfile = fopen( "/var/run/ripd.pid", "w" ) ;
	if (pidfile==NULL)
	{
	    fprintf(stderr,"%% Error write pid\n");
	    return (-1);
	}
	else fprintf(pidfile,"%d", (int) getpid());
	fclose(pidfile);    
	/*
	 * Any extra argument is considered
	 * a tracing log file.
	 * 
	 * Note: because traceon() redirects stderr, anything planning to
	 * crash on startup should do so before this point.
	 */

	if (argc > optind) {
		traceon(argv[optind]);
	}
	while (tflags-- > 0) {
		bumploglevel();
	}

	gettimeofday(&now, NULL);

	/*
	 * Collect an initial view of the world by
	 * checking the interface configuration and the gateway kludge
	 * file.  Then, send a request packet on all
	 * directly connected networks to find out what
	 * everyone else thinks.
	 */

	rtinit();
	ifinit();
	gwkludge();
	if (gateway > 0) {
		rtdefault();
	}
	if (supplier < 0) {
		supplier = 0;
	}
	query->rip_cmd = RIPCMD_REQUEST;
	query->rip_vers = RIPVERSION;
	if (sizeof(query->rip_nets[0].rip_dst.sa_family) > 1) {
		/* XXX */
		query->rip_nets[0].rip_dst.sa_family = htons((u_short)AF_UNSPEC);
	}
	else {
		/* unreachable code (at least on most platforms) */
		query->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
	}
	query->rip_nets[0].rip_metric = htonl((u_long)HOPCNT_INFINITY);

	toall(sndmsg, 0, NULL);

	signal(SIGALRM, timer);
	signal(SIGHUP, hup);
	signal(SIGTERM, hup);
	signal(SIGINT, rtdeleteall);
	signal(SIGUSR1, sigtrace);
	signal(SIGUSR2, sigtrace);

	itval.it_interval.tv_sec = TIMER_RATE;
	itval.it_value.tv_sec = TIMER_RATE;
	itval.it_interval.tv_usec = 0;
	itval.it_value.tv_usec = 0;

	srandom(time(NULL) ^ getpid());

	if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) {
		syslog(LOG_ERR, "setitimer: %m\n");
	}

	FD_ZERO(&ibits);
	nfd = sock + 1;			/* 1 + max(fd's) */
	for (;;) {
		FD_SET(sock, &ibits);

		/*
		 * If we need a dynamic update that was held off,
		 * needupdate will be set, and nextbcast is the time
		 * by which we want select to return.  Compute time
		 * until dynamic update should be sent, and select only
		 * until then.  If we have already passed nextbcast,
		 * just poll.
		 */
		if (needupdate) {
			waittime = nextbcast;
			timevalsub(&waittime, &now);
			if (waittime.tv_sec < 0) {
				waittime.tv_sec = 0;
				waittime.tv_usec = 0;
			}
			if (traceactions)
				fprintf(ftrace,
				 "select until dynamic update %ld/%ld sec/usec\n",
				    (long)waittime.tv_sec, (long)waittime.tv_usec);
			tvp = &waittime;
		}
		else {
			tvp = (struct timeval *)NULL;
		}

		n = select(nfd, &ibits, 0, 0, tvp);
		if (n <= 0) {
			/*
			 * Need delayed dynamic update if select returned
			 * nothing and we timed out.  Otherwise, ignore
			 * errors (e.g. EINTR).
			 */
			if (n < 0) {
				if (errno == EINTR)
					continue;
				syslog(LOG_ERR, "select: %m");
			}
			sigemptyset(&sigset);
			sigaddset(&sigset, SIGALRM);
			sigprocmask(SIG_BLOCK, &sigset, &osigset);
			if (n == 0 && needupdate) {
				if (traceactions)
					fprintf(ftrace,
					    "send delayed dynamic update\n");
				(void) gettimeofday(&now,
					    (struct timezone *)NULL);
				toall(supply, RTS_CHANGED,
				    (struct interface *)NULL);
				lastbcast = now;
				needupdate = 0;
				nextbcast.tv_sec = 0;
			}
			sigprocmask(SIG_SETMASK, &osigset, NULL);
			continue;
		}

		gettimeofday(&now, (struct timezone *)NULL);
		sigemptyset(&sigset);
		sigaddset(&sigset, SIGALRM);
		sigprocmask(SIG_BLOCK, &sigset, &osigset);

		if (FD_ISSET(sock, &ibits)) {
			process(sock);
		}

		/* handle ICMP redirects */
		sigprocmask(SIG_SETMASK, &osigset, NULL);
	}
}
コード例 #10
0
ファイル: inLib.c プロジェクト: phoboz/vmx
int in_control(struct socket *so,
               unsigned long cmd,
               void *data,
               struct ifnet *ifp)
{
  struct ifreq *ifr;
  struct in_ifaddr *ia, *oia;
  struct ifaddr *ifa;
  struct in_aliasreq *ifra;
  struct sockaddr_in oldaddr;
  int err, newroute, newmask, newhost;
  unsigned long i;

  /* Initialize local */
  ifr = (struct ifreq *) data;
  ia = NULL;
  ifra = (struct in_aliasreq *) data;
  err = 0;
  newroute = 0;

  /* If interface argument sent */
  if (ifp != NULL) {
 
    /* For all interfaces */
    for (ia = in_ifaddr; ia != NULL; ia = ia->ia_next)
      if (ia->ia_ifp == ifp)
        break;

  } /* End if interface argument sent */

  /******************************************/
  /* Select command part1 - Initialize data */
  /******************************************/
  switch(cmd) {

    case SIOCAIFADDR:

      if (ia == NULL)
        newroute = 1;

      /* FALL TRU */

    case SIOCDIFADDR:

      /* If internet family */
      if (ifra->ifra_addr.sin_family == AF_INET) {

        /* For all interface addresses */
        for (oia = ia; ia != NULL; ia = ia->ia_next) {

          if ((ia->ia_ifp == ifp) &&
              (ia->ia_addr.sin_addr.s_addr == ifra->ifra_addr.sin_addr.s_addr))
            break;

        } /* End for all interface addresses */

      } /* End if internet family */

      if ( (cmd == SIOCDIFADDR) && (ia == NULL) )
        return EADDRNOTAVAIL;
 
      /* FALL TRU */

    case SIOCSIFADDR:
    case SIOCSIFNETMASK:
    case SIOCSIFDSTADDR:

      if ( (so->so_state & SS_PRIV) == 0 )
        return EPERM;

      if (ifp == NULL)
        panic("in control");


      /* If need to alloc */
      if (ia == NULL) {

        oia = mb_alloc(sizeof(struct in_ifaddr), MT_IFADDR, M_WAIT);
        if (oia == NULL)
          return ENOBUFS;

      } /* End if need to alloc */

      /* Clear address */
      memset(oia, 0, sizeof(struct in_ifaddr));

      /* Add address to address list */
      ia = in_ifaddr;

      /* If any addresses exists */
      if (ia != NULL) {

        /* Go to end of address list */
        for (; ia->ia_next != NULL; ia = ia->ia_next)
          continue;

        /* Set address */
        ia->ia_next = oia;

      } /* End if any addresses exists */

      /* Else no addresses exists */
      else {

        /* Set address */
        in_ifaddr = oia;

      } /* End else no addresses exists */

      /* Add address to interface address list */
      ia = oia;
      ifa = ifp->if_addrlist;

      /* If any addresses in interface address list */
      if (ifa != NULL) {

        /* Move to last address */
        for ( ; ifa->ifa_next != NULL; ifa = ifa->ifa_next)
          continue;

        /* Set address */
        ifa->ifa_next = (struct ifaddr *) ia;

      } /* End if any addresses in interface address list */

      /* Else no addresses in interface address list */
      else {

        /* Set address */
        ifp->if_addrlist = (struct ifaddr *) ia;

      } /* End else no addresses in interface address list */

      /* Setup address struct */
      ia->ia_ifa.ifa_addr = (struct sockaddr *) &ia->ia_addr;
      ia->ia_ifa.ifa_dstaddr = (struct sockaddr *) &ia->ia_dstaddr;
      ia->ia_ifa.ifa_netmask = (struct sockaddr *) &ia->ia_netmask;
      ia->ia_sockmask.sin_len = 8;

      /* If broadcast available */
      if (ifp->if_flags & IFF_BROADCAST) {

        ia->ia_broadaddr.sin_len = sizeof(struct sockaddr_in);
        ia->ia_broadaddr.sin_family = AF_INET;

      } /* End if broadcast available */

      /* Set interface point in address */
      ia->ia_ifp = ifp;

      if (ifp != loif)
        in_interfaces++;

    break;

    case SIOCSIFBRDADDR:

      if ( (so->so_state & SS_PRIV) == 0 )
        return EPERM;

      /* FALL TRU */

    case SIOCGIFADDR:
    case SIOCGIFNETMASK:
    case SIOCGIFDSTADDR:
    case SIOCGIFBRDADDR:

      if (ia == NULL)
        return EADDRNOTAVAIL;

    break;

  } /* End select command part1 - Initialize data */

  /******************************************/
  /* Select command part2 - Execute command */
  /******************************************/
  switch(cmd) {

    case SIOCGIFADDR:

      /* Get address */
      *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;

    break;

    case SIOCGIFBRDADDR:

      if ( (ifp->if_flags & IFF_BROADCAST) == 0 )
        return EINVAL;

      /* Get address */
      *((struct sockaddr_in *) &ifr->ifr_dstaddr) = ia->ia_broadaddr;

    break;

    case SIOCGIFDSTADDR:

      if ( (ifp->if_flags & IFF_POINTOPOINT) == 0 )
        return EINVAL;

      /* Get address */
      *((struct sockaddr_in *) &ifr->ifr_dstaddr) = ia->ia_dstaddr;

    break;

    case SIOCGIFNETMASK:

      /* Get mask */
      *((struct sockaddr_in *) &ifr->ifr_addr) = ia->ia_sockmask;

    break;

    case SIOCSIFDSTADDR:

      if ( (ifp->if_flags & IFF_POINTOPOINT) == 0 )
        return EINVAL;

      /* Set address */
      oldaddr = ia->ia_dstaddr;
      ia->ia_dstaddr = *(struct sockaddr_in *) &ifr->ifr_dstaddr;

      /* If interface ioctl fails */
      if ( (ifp->if_ioctl != NULL) &&
           (err = ( *ifp->if_ioctl) (ifp, SIOCSIFDSTADDR, ia)) ) {

        ia->ia_dstaddr = oldaddr;
        return err;

      } /* If interface ioctl fails */

      /* If route */
      if (ia->ia_flags & IFA_ROUTE) {

        /* Delete old route */
        ia->ia_ifa.ifa_dstaddr = (struct sockaddr *) &oldaddr;
        rtinit(&(ia->ia_ifa), RTM_DELETE, RTF_HOST);

        /* Add new route */
        ia->ia_ifa.ifa_dstaddr = (struct sockaddr *) &ia->ia_dstaddr;
        rtinit(&(ia->ia_ifa), RTM_ADD, RTF_HOST | RTF_UP);

      } /* If route */

    break;

    case SIOCSIFBRDADDR:

      if ( (ifp->if_flags & IFF_BROADCAST) == 0 )
        return EINVAL;

      /* Set address */
      ia->ia_broadaddr = *(struct sockaddr_in *) &ifr->ifr_broadaddr;

    break;

    case SIOCSIFADDR:

      return in_ifinit(ifp, ia, (struct sockaddr_in *) &ifr->ifr_addr, 1);

    case SIOCSIFNETMASK:

      i = ifra->ifra_addr.sin_addr.s_addr;
      ia->ia_sockmask.sin_addr.s_addr = i;
      ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr);
      in_socktrim(&ia->ia_sockmask);

    break;

    case SIOCAIFADDR:

      newmask = 0;
      newhost = 1;

      /* If inet family */
      if (ia->ia_addr.sin_family == AF_INET) {

        /* If zero length */
        if (ifra->ifra_addr.sin_len == 0) {

          ifra->ifra_addr = ia->ia_addr;
          newhost = 0;

        } /* End if zero length */

        /* Else if address match */
        else if (ifra->ifra_addr.sin_addr.s_addr ==
                 ia->ia_addr.sin_addr.s_addr) {

          newhost = 0;

        } /* End else if address match */

      } /* End if inet family */

      /* If mask length non-zero */
      if (ifra->ifra_mask.sin_len) {

        in_ifscrub(ifp, ia);
        ia->ia_sockmask = ifra->ifra_mask;
        ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr);
        newmask = 1;

      } /* End if mask length non-zero */

      /* If point-to-point and inet */
      if ( (ifp->if_flags & IFF_POINTOPOINT) &&
           (ifra->ifra_dstaddr.sin_family == AF_INET) ) {

        in_ifscrub(ifp, ia);
        ia->ia_dstaddr = ifra->ifra_dstaddr;
        newmask = 1;

      } /* End if point-to-point and inet */

      if ( (ifra->ifra_addr.sin_family == AF_INET) &&
           (newhost || newmask) )
        err = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);

      if ( (err == EEXIST) && !newroute)
        err = 0;

      if ( (ifp->if_flags & IFF_BROADCAST) &&
           (ifra->ifra_broadaddr.sin_family == AF_INET) &&
           (ifra->ifra_broadaddr.sin_addr.s_addr) )
        ia->ia_broadaddr = ifra->ifra_broadaddr;

      return err;

    case SIOCDIFADDR:

      in_ifscrub(ifp, ia);

      /* Get interface address list */
      ifa = ifp->if_addrlist;

      /* If the same address list */
      if (ifa == (struct ifaddr *) ia) {

        ifp->if_addrlist = ifa->ifa_next;

      } /* End if the same address list */

      /* Else not the same address list */
      else {

        /* Move until end or match */
        while ( (ifa->ifa_next != NULL) &&
                (ifa->ifa_next != (struct ifaddr *) ia) )
          ifa = ifa->ifa_next;

        if (ifa->ifa_next != NULL)
          ifa->ifa_next = ((struct ifaddr *) ia)->ifa_next;
        else
          panic("link inifaddr");

      } /* End else not the same address list */

      oia = ia;
      ia = in_ifaddr;

      /* If old is first element */
      if (oia == ia) {

        in_ifaddr = ia->ia_next;

      } /* End if old is first element */

      /* Else old is not first element */
      else {

        /* Move until end or match */
        while ( (ia->ia_next != NULL) &&
                (ia->ia_next != oia) )
          ia = ia->ia_next;

        if (ia->ia_next != NULL)
          ia->ia_next = oia->ia_next;
        else
          panic("unlink inifaddr");

      } /* End else old is not first element */

      IFAFREE(&oia->ia_ifa);

    break;

    default:

      if ( (ifp == NULL) || (ifp->if_ioctl == NULL) )
        return EOPNOTSUPP;

      return ( *ifp->if_ioctl) (ifp, cmd, data);

  } /* End select command part2 - Execute command */

  return 0;
}
コード例 #11
0
ファイル: inLib.c プロジェクト: phoboz/vmx
int in_ifinit(struct ifnet *ifp,
              struct in_ifaddr *ia,
              struct sockaddr_in *sin,
              int scrub)
{
  int s, flags, err;
  unsigned long i;
  struct sockaddr_in oldaddr;

  /* Initialize locals */
  err = 0;
  i = ntohl(sin->sin_addr.s_addr);
  flags = RTF_UP;

  /* Get processor level */
  s = splimp();

  /* Store old address */
  oldaddr = ia->ia_addr;

  /* Set new address */
  ia->ia_addr = *sin;

  /* If ioctl function */
  if (ifp->if_ioctl != NULL) {

    /* Initialize interface */
    err = ( *ifp->if_ioctl) (ifp, SIOCSIFADDR, ia);
    if (err) {

      splx(s);
      ia->ia_addr = oldaddr;
      return err;

    }

  } /* End if ioctl function */

  /* Restore processor level */
  splx(s);

  /* If scrub requested */
  if (scrub) {

    ia->ia_ifa.ifa_addr = (struct sockaddr *) &oldaddr;
    in_ifscrub(ifp, ia);
    ia->ia_ifa.ifa_addr = (struct sockaddr *) &ia->ia_addr;

  } /* End if scrub requested */

  /* Setup netmask */
  if ( IN_CLASSA(i) )
    ia->ia_netmask = IN_CLASSA_NET;
  else if ( IN_CLASSB(i) )
    ia->ia_netmask = IN_CLASSB_NET;
  else
    ia->ia_netmask = IN_CLASSC_NET;

  /* If subnet mask zero */
  if (ia->ia_subnetmask == 0) {

    ia->ia_subnetmask = ia->ia_netmask;
    ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);

  } /* End if subnet mask zero */

  /* Else subnet mask non-zero */
  else {

    ia->ia_netmask &= ia->ia_subnetmask;

  } /* End else subnet mask non-zero */

  /* Set net */
  ia->ia_net = i & ia->ia_netmask;
  ia->ia_subnet = i & ia->ia_subnetmask;
  in_socktrim(&ia->ia_sockmask);

  /* Add route for network */
  ia->ia_ifa.ifa_metric = ifp->if_metric;

  /* If broadcast */
  if (ifp->if_flags & IFF_BROADCAST) {

    ia->ia_broadaddr.sin_addr.s_addr =
        htonl(ia->ia_subnet | ~ia->ia_subnetmask);

    ia->ia_netbroadcast.s_addr =
        htonl(ia->ia_net | ~ia->ia_netmask);

  } /* End if broadcast */

  /* Else if loopback */
  else if (ifp->if_flags & IFF_LOOPBACK) {

    ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
    flags |= RTF_HOST;

  } /* End else if loopback */

  /* Else if pointopoint */
  else if (ifp->if_flags & IFF_POINTOPOINT) {

    if (ia->ia_dstaddr.sin_family != AF_INET)
      return 0;

    flags |= RTF_HOST;

  } /* End else if pointopoint */

  /* Initialize route */
  err = rtinit(&ia->ia_ifa, RTM_ADD, flags);
  if (err == 0)
    ia->ia_flags |= IFA_ROUTE;

  return err;
}
コード例 #12
0
ファイル: main.c プロジェクト: appleorange1/asus-rt-n12-lx
int
main(int argc, char *argv[])
{
	int _argc = 0;
	char *_argv[5];
	pid_t pid;
	int execed = 0;

	int n, nfd, tflags = 0, ch;
	struct timeval *tvp, waittime;
	struct itimerval itval;
	fd_set ibits;
	sigset_t sigset, osigset;

	while ((ch = getopt(argc, argv, "D012bsqtdg")) != EOF) {
		switch (ch) {
			case 'D':
				execed = 1;
				break;
			case '0': ripversion = 0; break;
			case '1': ripversion = 1; break;
			case '2': ripversion = 2; break;
			case 'b': multicast = 0; break;
			case 's': supplier = 1; break;
			case 'q': supplier = 0; break;
			case 't': 
				tflags++;
				break;
			case 'd': 
				debug++;
				setlogmask(LOG_UPTO(LOG_DEBUG));
				break;
			case 'g': gateway = 1; break;
			default:
				fprintf(stderr, "usage: routed [ -1bsqtdg ]\n");
				exit(1);
		}
	}
	
	// Modified by Mason Yu
	sleep(2);
	/*
	if(!check_pid()) {
		// Commented by Mason Yu
		//write_cfg();
		exit(1);
	}
	*/
	
	if (!execed) {
		if ((pid = vfork()) < 0) {
			fprintf(stderr, "vfork failed\n");
			exit(1);
		} else if (pid != 0) {
			exit(0);
		}
		
		for (_argc=0; _argc < argc; _argc++ )
			_argv[_argc] = argv[_argc];
		_argv[0] = runPath;
		_argv[argc++] = "-D";
		_argv[argc++] = NULL;
		execv(_argv[0], _argv);
		/* Not reached */
		fprintf(stderr, "Couldn't exec\n");
		_exit(1);

	} else {
		setsid();
	}

	getkversion();

	sock = getsocket();
	assert(sock>=0);

	openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON);

#if 0
	if (debug == 0 && tflags == 0) {
#ifndef EMBED
		switch (fork()) {
			case -1: perror("fork"); exit(1);
			case 0: break;  /* child */
			default: exit(0);   /* parent */
		}
#endif
		close(0);
		close(1);
		close(2);
		setsid();
		setlogmask(LOG_UPTO(LOG_WARNING));
	}
	else 
#endif
	{
		setlogmask(LOG_UPTO(LOG_DEBUG));
	}

	/*
	 * Any extra argument is considered
	 * a tracing log file.
	 * 
	 * Note: because traceon() redirects stderr, anything planning to
	 * crash on startup should do so before this point.
	 */

	if (argc > 1) {
		traceon(argv[argc - 1]);
	}
	while (tflags-- > 0) {
		bumploglevel();
	}

	gettimeofday(&now, NULL);

	/*
	 * Collect an initial view of the world by
	 * checking the interface configuration and the gateway kludge
	 * file.  Then, send a request packet on all
	 * directly connected networks to find out what
	 * everyone else thinks.
	 */
	 read_cfg();
	rtinit();
	ifinit();
	gwkludge();

	if (gateway > 0) {
		rtdefault();
	}

	if (supplier < 0) {
		supplier = 0;
	}

	signal(SIGALRM, timer);
	signal(SIGHUP, hup);
	signal(SIGTERM, hup);
        signal(SIGTERM, terminate_routed); //RTK WiSOC modify for deleting all route entry
	signal(SIGINT, rtdeleteall);
	signal(SIGUSR1, sigtrace);
	signal(SIGUSR2, sigtrace);

	itval.it_interval.tv_sec = TIMER_RATE;
	itval.it_value.tv_sec = TIMER_RATE;
	itval.it_interval.tv_usec = 0;
	itval.it_value.tv_usec = 0;

	srandom(time(NULL) ^ getpid());

	if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) {
		syslog(LOG_ERR, "setitimer: %m\n");
	}
	
	// Kaohj
//#ifdef EMBED //WiSOC we use pid file for system init
	write_pid();
//#endif
	rip_request_send();
	rip_input_init();
	DISPLAY_BANNER;
	FD_ZERO(&ibits);
	nfd = sock + 1;			/* 1 + max(fd's) */
	for (;;) {
		FD_SET(sock, &ibits);

		/*
		 * If we need a dynamic update that was held off,
		 * needupdate will be set, and nextbcast is the time
		 * by which we want select to return.  Compute time
		 * until dynamic update should be sent, and select only
		 * until then.  If we have already passed nextbcast,
		 * just poll.
		 */
		if (needupdate) {
			waittime = nextbcast;
			timevalsub(&waittime, &now);
			if (waittime.tv_sec < 0) {
				waittime.tv_sec = 0;
				waittime.tv_usec = 0;
			}
			if (traceactions)
				fprintf(ftrace,
				 "select until dynamic update %ld/%ld sec/usec\n",
				    (long)waittime.tv_sec, (long)waittime.tv_usec);
			tvp = &waittime;
		}
		else {
			tvp = (struct timeval *)NULL;
		}

		n = select(nfd, &ibits, 0, 0, tvp);
		if (n <= 0) {
			/*
			 * Need delayed dynamic update if select returned
			 * nothing and we timed out.  Otherwise, ignore
			 * errors (e.g. EINTR).
			 */
			if (n < 0) {
				if (errno == EINTR)
					continue;
				syslog(LOG_ERR, "select: %m");
			}
			sigemptyset(&sigset);
			sigaddset(&sigset, SIGALRM);
			sigprocmask(SIG_BLOCK, &sigset, &osigset);
			if (n == 0 && needupdate) {
				if (traceactions)
					fprintf(ftrace,
					    "send delayed dynamic update\n");
				(void) gettimeofday(&now,
					    (struct timezone *)NULL);
				toall(supply, RTS_CHANGED,
				    (struct interface *)NULL);
				lastbcast = now;
				needupdate = 0;
				nextbcast.tv_sec = 0;
			}
			sigprocmask(SIG_SETMASK, &osigset, NULL);
			continue;
		}

		gettimeofday(&now, (struct timezone *)NULL);
		sigemptyset(&sigset);
		sigaddset(&sigset, SIGALRM);
		sigprocmask(SIG_BLOCK, &sigset, &osigset);

		if (FD_ISSET(sock, &ibits)) {
			process(sock);
		}

		/* handle ICMP redirects */
		sigprocmask(SIG_SETMASK, &osigset, NULL);
	}
}
コード例 #13
0
ファイル: main.c プロジェクト: AhmadTux/DragonFlyBSD
int
main(int argc, char *argv[])
{
	int nfds;
	fd_set fdvar;
	time_t ttime;
	struct itimerval tval;

	argv0 = argv;
	argv++, argc--;
	while (argc > 0 && **argv == '-') {
		if (strcmp(*argv, "-s") == 0) {
			supplier = 1;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-q") == 0) {
			supplier = 0;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-R") == 0) {
			noteremoterequests++;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-S") == 0) {
			dosap = 0;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-t") == 0) {
			tracepackets++;
			argv++, argc--;
			ftrace = stderr;
			tracing = 1; 
			continue;
		}
		if (strcmp(*argv, "-g") == 0) {
			gateway = 1;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-l") == 0) {
			gateway = -1;
			argv++, argc--;
			continue;
		}
		if (strcmp(*argv, "-N") == 0) {
			dognreply = 0;
			argv++, argc--;
			continue;
		}
		fprintf(stderr,
			"usage: ipxrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ] [ -N ]\n");
		exit(1);
	}
	
	
#ifndef DEBUG
	if (!tracepackets)
		daemon(0, 0);
#endif
	openlog("IPXrouted", LOG_PID, LOG_DAEMON);

	addr.sipx_family = AF_IPX;
	addr.sipx_len = sizeof(addr);
	addr.sipx_port = htons(IPXPORT_RIP);
	ipx_anynet.s_net[0] = ipx_anynet.s_net[1] = -1;
	ipx_netmask.sipx_addr.x_net = ipx_anynet;
	ipx_netmask.sipx_len = 6;
	ipx_netmask.sipx_family = AF_IPX;
	r = socket(AF_ROUTE, SOCK_RAW, 0);
	/* later, get smart about lookingforinterfaces */
	if (r)
		shutdown(r, SHUT_RD); /* for now, don't want reponses */
	else {
		fprintf(stderr, "IPXrouted: no routing socket\n");
		exit(1);
	}
	ripsock = getsocket(SOCK_DGRAM, 0, &addr);
	if (ripsock < 0)
		exit(1);

	if (dosap) {
		addr.sipx_port = htons(IPXPORT_SAP);
		sapsock = getsocket(SOCK_DGRAM, 0, &addr);
		if (sapsock < 0)
			exit(1);
	} else
		sapsock = -1;

	/*
	 * Any extra argument is considered
	 * a tracing log file.
	 */
	if (argc > 0)
		traceon(*argv);
	/*
	 * Collect an initial view of the world by
	 * snooping in the kernel.  Then, send a request packet on all
	 * directly connected networks to find out what
	 * everyone else thinks.
	 */
	rtinit();
	sapinit();
	ifinit();
	if (supplier < 0)
		supplier = 0;
	/* request the state of the world */
	msg->rip_cmd = htons(RIPCMD_REQUEST);
	msg->rip_nets[0].rip_dst = ipx_anynet;
	msg->rip_nets[0].rip_metric =  htons(HOPCNT_INFINITY);
	msg->rip_nets[0].rip_ticks =  htons(-1);
	toall(sndmsg, NULL, 0);

	if (dosap) {
		sap_msg->sap_cmd = htons(SAP_REQ);
		sap_msg->sap[0].ServType = htons(SAP_WILDCARD);
		toall(sapsndmsg, NULL, 0);
	}

	signal(SIGALRM, catchtimer);
	signal(SIGHUP, hup);
	signal(SIGINT, hup);
	signal(SIGEMT, fkexit);
	signal(SIGINFO, getinfo);
 
	tval.it_interval.tv_sec = TIMER_RATE;
	tval.it_interval.tv_usec = 0;
	tval.it_value.tv_sec = TIMER_RATE;
	tval.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &tval, NULL);

	nfds = 1 + max(sapsock, ripsock);

	for (;;) {
		if (dobcast) {
			dobcast = 0;
			lastbcast = time(NULL);
			timer();
		}

		FD_ZERO(&fdvar);
		if (dosap) {
			FD_SET(sapsock, &fdvar);
		}
		FD_SET(ripsock, &fdvar);

		if(select(nfds, &fdvar, NULL, NULL, NULL) < 0) {
			if(errno == EINTR)
				continue;
			perror("during select");
			exit(1);
		}

		if(FD_ISSET(ripsock, &fdvar))
			process(ripsock, RIP_PKT);

		if(dosap && FD_ISSET(sapsock, &fdvar))
			process(sapsock, SAP_PKT);

		ttime = time(NULL);
		if (ttime > (lastbcast + TIMER_RATE + (TIMER_RATE * 2 / 3))) {
			dobcast = 1;
			syslog(LOG_ERR, "Missed alarm");
		}
	}
}
コード例 #14
0
/*
 * Generic internet control operations (ioctl's).
 */
int
ipx_control_oncpu(struct socket *so, u_long cmd, caddr_t data,
	struct ifnet *ifp, struct thread *td)
{
	struct ifreq *ifr = (struct ifreq *)data;
	struct ipx_aliasreq *ifra = (struct ipx_aliasreq *)data;
	struct ipx_ifaddr *ia;
	struct ifaddr *ifa;
	struct ipx_ifaddr *oia;
	int dstIsNew, hostIsNew;
	int error = 0;

	/*
	 * Find address for this interface, if it exists.
	 */
	if (ifp == NULL)
		return (EADDRNOTAVAIL);
	for (ia = ipx_ifaddr; ia != NULL; ia = ia->ia_next)
		if (ia->ia_ifp == ifp)
			break;

	switch (cmd) {

	case SIOCGIFADDR:
		if (ia == NULL)
			return (EADDRNOTAVAIL);
		*(struct sockaddr_ipx *)&ifr->ifr_addr = ia->ia_addr;
		return (0);

	case SIOCGIFBRDADDR:
		if (ia == NULL)
			return (EADDRNOTAVAIL);
		if ((ifp->if_flags & IFF_BROADCAST) == 0)
			return (EINVAL);
		*(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_broadaddr;
		return (0);

	case SIOCGIFDSTADDR:
		if (ia == NULL)
			return (EADDRNOTAVAIL);
		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
			return (EINVAL);
		*(struct sockaddr_ipx *)&ifr->ifr_dstaddr = ia->ia_dstaddr;
		return (0);
	}

	if ((error = priv_check(td, PRIV_ROOT)) != 0)
		return (error);

	switch (cmd) {
	case SIOCAIFADDR:
	case SIOCDIFADDR:
		if (ifra->ifra_addr.sipx_family == AF_IPX)
		    for (oia = ia; ia != NULL; ia = ia->ia_next) {
			if (ia->ia_ifp == ifp  &&
			    ipx_neteq(ia->ia_addr.sipx_addr,
				  ifra->ifra_addr.sipx_addr))
			    break;
		    }
		if (cmd == SIOCDIFADDR && ia == NULL)
			return (EADDRNOTAVAIL);
		/* FALLTHROUGH */

	case SIOCSIFADDR:
	case SIOCSIFDSTADDR:
		if (ia == NULL) {
			oia = ifa_create(sizeof(*ia), M_WAITOK);
			if ((ia = ipx_ifaddr) != NULL) {
				for ( ; ia->ia_next != NULL; ia = ia->ia_next)
					;
				ia->ia_next = oia;
			} else
				ipx_ifaddr = oia;
			ia = oia;
			ifa = (struct ifaddr *)ia;
			ifa_iflink(ifa, ifp, 1);
			ia->ia_ifp = ifp;
			ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;

			ifa->ifa_netmask = (struct sockaddr *)&ipx_netmask;

			ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
			if (ifp->if_flags & IFF_BROADCAST) {
				ia->ia_broadaddr.sipx_family = AF_IPX;
				ia->ia_broadaddr.sipx_len = sizeof(ia->ia_addr);
				ia->ia_broadaddr.sipx_addr.x_host = ipx_broadhost;
			}
		}
	}

	switch (cmd) {

	case SIOCSIFDSTADDR:
		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
			return (EINVAL);
		if (ia->ia_flags & IFA_ROUTE) {
			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
			ia->ia_flags &= ~IFA_ROUTE;
		}
		if (ifp->if_ioctl) {
			ifnet_serialize_all(ifp);
			error = ifp->if_ioctl(ifp, SIOCSIFDSTADDR,
					      (void *)ia, td->td_proc->p_ucred);
			ifnet_deserialize_all(ifp);
			if (error)
				return (error);
		}
		*(struct sockaddr *)&ia->ia_dstaddr = ifr->ifr_dstaddr;
		return (0);

	case SIOCSIFADDR:
		return (ipx_ifinit(ifp, ia,
				(struct sockaddr_ipx *)&ifr->ifr_addr, 1));

	case SIOCDIFADDR:
		ipx_ifscrub(ifp, ia);
		ifa = (struct ifaddr *)ia;
		ifa_ifunlink(ifa, ifp);
		oia = ia;
		if (oia == (ia = ipx_ifaddr)) {
			ipx_ifaddr = ia->ia_next;
		} else {
			while (ia->ia_next && (ia->ia_next != oia)) {
				ia = ia->ia_next;
			}
			if (ia->ia_next)
			    ia->ia_next = oia->ia_next;
			else
				kprintf("Didn't unlink ipxifadr from list\n");
		}
		ifa_destroy(&oia->ia_ifa);
		return (0);
	
	case SIOCAIFADDR:
		dstIsNew = 0;
		hostIsNew = 1;
		if (ia->ia_addr.sipx_family == AF_IPX) {
			if (ifra->ifra_addr.sipx_len == 0) {
				ifra->ifra_addr = ia->ia_addr;
				hostIsNew = 0;
			} else if (ipx_neteq(ifra->ifra_addr.sipx_addr,
					 ia->ia_addr.sipx_addr))
				hostIsNew = 0;
		}
		if ((ifp->if_flags & IFF_POINTOPOINT) &&
		    (ifra->ifra_dstaddr.sipx_family == AF_IPX)) {
			if (hostIsNew == 0)
				ipx_ifscrub(ifp, ia);
			ia->ia_dstaddr = ifra->ifra_dstaddr;
			dstIsNew  = 1;
		}
		if (ifra->ifra_addr.sipx_family == AF_IPX &&
					    (hostIsNew || dstIsNew))
			error = ipx_ifinit(ifp, ia, &ifra->ifra_addr, 0);
		return (error);

	default:
		if (ifp->if_ioctl == NULL)
			return (EOPNOTSUPP);
		ifnet_serialize_all(ifp);
		error = ifp->if_ioctl(ifp, cmd, data, td->td_proc->p_ucred);
		ifnet_deserialize_all(ifp);
		return (error);
	}
}
コード例 #15
0
ファイル: proto.c プロジェクト: Claruarius/stblinux-2.6.37
static void
parseproto(
	xfs_mount_t	*mp,
	xfs_inode_t	*pip,
	struct fsxattr	*fsxp,
	char		**pp,
	char		*name)
{
#define	IF_REGULAR	0
#define	IF_RESERVED	1
#define	IF_BLOCK	2
#define	IF_CHAR		3
#define	IF_DIRECTORY	4
#define	IF_SYMLINK	5
#define	IF_FIFO		6

	char		*buf;
	int		committed;
	int		error;
	xfs_fsblock_t	first;
	int		flags;
	xfs_bmap_free_t	flist;
	int		fmt;
	int		i;
	xfs_inode_t	*ip;
	int		len;
	long long	llen;
	int		majdev;
	int		mindev;
	int		mode;
	char		*mstr;
	xfs_trans_t	*tp;
	int		val;
	int		isroot = 0;
	cred_t		creds;
	char		*value;
	struct xfs_name	xname;

	memset(&creds, 0, sizeof(creds));
	mstr = getstr(pp);
	switch (mstr[0]) {
	case '-':
		fmt = IF_REGULAR;
		break;
	case 'r':
		fmt = IF_RESERVED;
		break;
	case 'b':
		fmt = IF_BLOCK;
		break;
	case 'c':
		fmt = IF_CHAR;
		break;
	case 'd':
		fmt = IF_DIRECTORY;
		break;
	case 'l':
		fmt = IF_SYMLINK;
		break;
	case 'p':
		fmt = IF_FIFO;
		break;
	default:
		fprintf(stderr, _("%s: bad format string %s\n"),
			progname, mstr);
		exit(1);
	}
	mode = 0;
	switch (mstr[1]) {
	case '-':
		break;
	case 'u':
		mode |= S_ISUID;
		break;
	default:
		fprintf(stderr, _("%s: bad format string %s\n"),
			progname, mstr);
		exit(1);
	}
	switch (mstr[2]) {
	case '-':
		break;
	case 'g':
		mode |= S_ISGID;
		break;
	default:
		fprintf(stderr, _("%s: bad format string %s\n"),
			progname, mstr);
		exit(1);
	}
	val = 0;
	for (i = 3; i < 6; i++) {
		if (mstr[i] < '0' || mstr[i] > '7') {
			fprintf(stderr, _("%s: bad format string %s\n"),
				progname, mstr);
			exit(1);
		}
		val = val * 8 + mstr[i] - '0';
	}
	mode |= val;
	creds.cr_uid = (int)getnum(pp);
	creds.cr_gid = (int)getnum(pp);
	xname.name = (uchar_t *)name;
	xname.len = name ? strlen(name) : 0;
	tp = libxfs_trans_alloc(mp, 0);
	flags = XFS_ILOG_CORE;
	xfs_bmap_init(&flist, &first);
	switch (fmt) {
	case IF_REGULAR:
		buf = newregfile(pp, &len);
		getres(tp, XFS_B_TO_FSB(mp, len));
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
					   &creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		flags |= newfile(tp, ip, &flist, &first, 0, 0, buf, len);
		if (buf)
			free(buf);
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		break;

	case IF_RESERVED:			/* pre-allocated space only */
		value = getstr(pp);
		llen = cvtnum(mp->m_sb.sb_blocksize, mp->m_sb.sb_sectsize, value);
		getres(tp, XFS_B_TO_FSB(mp, llen));

		error = libxfs_inode_alloc(&tp, pip, mode|S_IFREG, 1, 0,
					  &creds, fsxp, &ip);
		if (error)
			fail(_("Inode pre-allocation failed"), error);

		libxfs_trans_ijoin(tp, pip, 0);

		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		libxfs_trans_log_inode(tp, ip, flags);

		error = libxfs_bmap_finish(&tp, &flist, &committed);
		if (error)
			fail(_("Pre-allocated file creation failed"), error);
		libxfs_trans_commit(tp, 0);
		rsvfile(mp, ip, llen);
		return;

	case IF_BLOCK:
		getres(tp, 0);
		majdev = (int)getnum(pp);
		mindev = (int)getnum(pp);
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFBLK, 1,
				IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
		if (error) {
			fail(_("Inode allocation failed"), error);
		}
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		flags |= XFS_ILOG_DEV;
		break;

	case IF_CHAR:
		getres(tp, 0);
		majdev = (int)getnum(pp);
		mindev = (int)getnum(pp);
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFCHR, 1,
				IRIX_MKDEV(majdev, mindev), &creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		flags |= XFS_ILOG_DEV;
		break;

	case IF_FIFO:
		getres(tp, 0);
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFIFO, 1, 0,
				&creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		break;
	case IF_SYMLINK:
		buf = getstr(pp);
		len = (int)strlen(buf);
		getres(tp, XFS_B_TO_FSB(mp, len));
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFLNK, 1, 0,
				&creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		flags |= newfile(tp, ip, &flist, &first, 1, 1, buf, len);
		libxfs_trans_ijoin(tp, pip, 0);
		newdirent(mp, tp, pip, &xname, ip->i_ino, &first, &flist, 1);
		libxfs_trans_ihold(tp, pip);
		break;
	case IF_DIRECTORY:
		getres(tp, 0);
		error = libxfs_inode_alloc(&tp, pip, mode|S_IFDIR, 1, 0,
				&creds, fsxp, &ip);
		if (error)
			fail(_("Inode allocation failed"), error);
		ip->i_d.di_nlink++;		/* account for . */
		if (!pip) {
			pip = ip;
			mp->m_sb.sb_rootino = ip->i_ino;
			libxfs_mod_sb(tp, XFS_SB_ROOTINO);
			mp->m_rootip = ip;
			isroot = 1;
		} else {
			libxfs_trans_ijoin(tp, pip, 0);
			newdirent(mp, tp, pip, &xname, ip->i_ino,
				  &first, &flist, 1);
			pip->i_d.di_nlink++;
			libxfs_trans_ihold(tp, pip);
			libxfs_trans_log_inode(tp, pip, XFS_ILOG_CORE);
		}
		newdirectory(mp, tp, ip, pip);
		libxfs_trans_log_inode(tp, ip, flags);
		error = libxfs_bmap_finish(&tp, &flist, &committed);
		if (error)
			fail(_("Directory creation failed"), error);
		libxfs_trans_ihold(tp, ip);
		libxfs_trans_commit(tp, 0);
		/*
		 * RT initialization.  Do this here to ensure that
		 * the RT inodes get placed after the root inode.
		 */
		if (isroot)
			rtinit(mp);
		tp = NULL;
		for (;;) {
			name = getstr(pp);
			if (!name)
				break;
			if (strcmp(name, "$") == 0)
				break;
			parseproto(mp, ip, fsxp, pp, name);
		}
		libxfs_iput(ip, 0);
		return;
	}
	libxfs_trans_log_inode(tp, ip, flags);
	error = libxfs_bmap_finish(&tp, &flist, &committed);
	if (error) {
		fail(_("Error encountered creating file from prototype file"),
			error);
	}
	libxfs_trans_commit(tp, 0);
}
コード例 #16
0
ファイル: phase5.c プロジェクト: chandanr/xfsprogs-dev
void
phase5(xfs_mount_t *mp)
{
	xfs_agnumber_t		agno;

	do_log(_("Phase 5 - rebuild AG headers and trees...\n"));
	set_progress_msg(PROG_FMT_REBUILD_AG, (__uint64_t )glob_agcount);

#ifdef XR_BLD_FREE_TRACE
	fprintf(stderr, "inobt level 1, maxrec = %d, minrec = %d\n",
		xfs_inobt_maxrecs(mp, mp->m_sb.sb_blocksize, 0),
		xfs_inobt_maxrecs(mp, mp->m_sb.sb_blocksize, 0) / 2);
	fprintf(stderr, "inobt level 0 (leaf), maxrec = %d, minrec = %d\n",
		xfs_inobt_maxrecs(mp, mp->m_sb.sb_blocksize, 1),
		xfs_inobt_maxrecs(mp, mp->m_sb.sb_blocksize, 1) / 2);
	fprintf(stderr, "xr inobt level 0 (leaf), maxrec = %d\n",
		XR_INOBT_BLOCK_MAXRECS(mp, 0));
	fprintf(stderr, "xr inobt level 1 (int), maxrec = %d\n",
		XR_INOBT_BLOCK_MAXRECS(mp, 1));
	fprintf(stderr, "bnobt level 1, maxrec = %d, minrec = %d\n",
		xfs_allocbt_maxrecs(mp, mp->m_sb.sb_blocksize, 0),
		xfs_allocbt_maxrecs(mp, mp->m_sb.sb_blocksize, 0) / 2);
	fprintf(stderr, "bnobt level 0 (leaf), maxrec = %d, minrec = %d\n",
		xfs_allocbt_maxrecs(mp, mp->m_sb.sb_blocksize, 1),
		xfs_allocbt_maxrecs(mp, mp->m_sb.sb_blocksize, 1) / 2);
#endif
	/*
	 * make sure the root and realtime inodes show up allocated
	 */
	keep_fsinos(mp);

	/* allocate per ag counters */
	sb_icount_ag = calloc(mp->m_sb.sb_agcount, sizeof(__uint64_t));
	if (sb_icount_ag == NULL)
		do_error(_("cannot alloc sb_icount_ag buffers\n"));

	sb_ifree_ag = calloc(mp->m_sb.sb_agcount, sizeof(__uint64_t));
	if (sb_ifree_ag == NULL)
		do_error(_("cannot alloc sb_ifree_ag buffers\n"));

	sb_fdblocks_ag = calloc(mp->m_sb.sb_agcount, sizeof(__uint64_t));
	if (sb_fdblocks_ag == NULL)
		do_error(_("cannot alloc sb_fdblocks_ag buffers\n"));

	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++)
		phase5_func(mp, agno);

	print_final_rpt();

	/* aggregate per ag counters */
	for (agno = 0; agno < mp->m_sb.sb_agcount; agno++)  {
		sb_icount += sb_icount_ag[agno];
		sb_ifree += sb_ifree_ag[agno];
		sb_fdblocks += sb_fdblocks_ag[agno];
	}
	free(sb_icount_ag);
	free(sb_ifree_ag);
	free(sb_fdblocks_ag);

	if (mp->m_sb.sb_rblocks)  {
		do_log(
		_("        - generate realtime summary info and bitmap...\n"));
		rtinit(mp);
		generate_rtinfo(mp, btmcompute, sumcompute);
	}

	do_log(_("        - reset superblock...\n"));

	/*
	 * sync superblock counter and set version bits correctly
	 */
	sync_sb(mp);

	bad_ino_btree = 0;

}