Example #1
0
static int
allocif(int unit, struct shmif_sc **scp)
{
	uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0xa0, 0x00, 0x00, 0x00, 0x00 };
	struct shmif_sc *sc;
	struct ifnet *ifp;
	uint32_t randnum;
	int error;

	randnum = cprng_fast32();
	memcpy(&enaddr[2], &randnum, sizeof(randnum));

	sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
	sc->sc_memfd = -1;
	sc->sc_unit = unit;
	sc->sc_uuid = cprng_fast64();

	ifp = &sc->sc_ec.ec_if;

	snprintf(ifp->if_xname, sizeof(ifp->if_xname), "shmif%d", unit);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_init = shmif_init;
	ifp->if_ioctl = shmif_ioctl;
	ifp->if_start = shmif_start;
	ifp->if_stop = shmif_stop;
	ifp->if_mtu = ETHERMTU;
	ifp->if_dlt = DLT_EN10MB;

	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
	cv_init(&sc->sc_cv, "shmifcv");

	if_initialize(ifp);
	ether_ifattach(ifp, enaddr);
	if_register(ifp);

	aprint_verbose("shmif%d: Ethernet address %s\n",
	    unit, ether_sprintf(enaddr));

	if (scp)
		*scp = sc;

	error = 0;
	if (rump_threads) {
		error = kthread_create(PRI_NONE,
		    KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL,
		    shmif_rcv, ifp, &sc->sc_rcvl, "shmif");
	} else {
		printf("WARNING: threads not enabled, shmif NOT working\n");
	}

	if (error) {
		shmif_unclone(ifp);
	}

	return error;
}
Example #2
0
void
tap_attach(device_t parent, device_t self, void *aux)
{
	struct tap_softc *sc = device_private(self);
	struct ifnet *ifp;
	const struct sysctlnode *node;
	int error;
	uint8_t enaddr[ETHER_ADDR_LEN] =
	    { 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff };
	char enaddrstr[3 * ETHER_ADDR_LEN];

	sc->sc_dev = self;
	sc->sc_sih = NULL;
	getnanotime(&sc->sc_btime);
	sc->sc_atime = sc->sc_mtime = sc->sc_btime;
	sc->sc_flags = 0;
	selinit(&sc->sc_rsel);

	/*
	 * Initialize the two locks for the device.
	 *
	 * We need a lock here because even though the tap device can be
	 * opened only once, the file descriptor might be passed to another
	 * process, say a fork(2)ed child.
	 *
	 * The Giant saves us from most of the hassle, but since the read
	 * operation can sleep, we don't want two processes to wake up at
	 * the same moment and both try and dequeue a single packet.
	 *
	 * The queue for event listeners (used by kqueue(9), see below) has
	 * to be protected too, so use a spin lock.
	 */
	mutex_init(&sc->sc_rdlock, MUTEX_DEFAULT, IPL_NONE);
	mutex_init(&sc->sc_kqlock, MUTEX_DEFAULT, IPL_VM);

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");

	/*
	 * In order to obtain unique initial Ethernet address on a host,
	 * do some randomisation.  It's not meant for anything but avoiding
	 * hard-coding an address.
	 */
	cprng_fast(&enaddr[3], 3);

	aprint_verbose_dev(self, "Ethernet address %s\n",
	    ether_snprintf(enaddrstr, sizeof(enaddrstr), enaddr));

	/*
	 * Why 1000baseT? Why not? You can add more.
	 *
	 * Note that there are 3 steps: init, one or several additions to
	 * list of supported media, and in the end, the selection of one
	 * of them.
	 */
	ifmedia_init(&sc->sc_im, 0, tap_mediachange, tap_mediastatus);
	ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_1000_T, 0, NULL);
	ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_1000_T|IFM_FDX, 0, NULL);
	ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_100_TX, 0, NULL);
	ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_100_TX|IFM_FDX, 0, NULL);
	ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_10_T, 0, NULL);
	ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
	ifmedia_add(&sc->sc_im, IFM_ETHER|IFM_AUTO, 0, NULL);
	ifmedia_set(&sc->sc_im, IFM_ETHER|IFM_AUTO);

	/*
	 * One should note that an interface must do multicast in order
	 * to support IPv6.
	 */
	ifp = &sc->sc_ec.ec_if;
	strcpy(ifp->if_xname, device_xname(self));
	ifp->if_softc	= sc;
	ifp->if_flags	= IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl	= tap_ioctl;
	ifp->if_start	= tap_start;
	ifp->if_stop	= tap_stop;
	ifp->if_init	= tap_init;
	IFQ_SET_READY(&ifp->if_snd);

	sc->sc_ec.ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU;

	/* Those steps are mandatory for an Ethernet driver. */
	if_initialize(ifp);
	ether_ifattach(ifp, enaddr);
	if_register(ifp);

	/*
	 * Add a sysctl node for that interface.
	 *
	 * The pointer transmitted is not a string, but instead a pointer to
	 * the softc structure, which we can use to build the string value on
	 * the fly in the helper function of the node.  See the comments for
	 * tap_sysctl_handler for details.
	 *
	 * Usually sysctl_createv is called with CTL_CREATE as the before-last
	 * component.  However, we can allocate a number ourselves, as we are
	 * the only consumer of the net.link.<iface> node.  In this case, the
	 * unit number is conveniently used to number the node.  CTL_CREATE
	 * would just work, too.
	 */
	if ((error = sysctl_createv(NULL, 0, NULL,
	    &node, CTLFLAG_READWRITE,
	    CTLTYPE_STRING, device_xname(self), NULL,
	    tap_sysctl_handler, 0, (void *)sc, 18,
	    CTL_NET, AF_LINK, tap_node, device_unit(sc->sc_dev),
	    CTL_EOL)) != 0)
		aprint_error_dev(self, "sysctl_createv returned %d, ignoring\n",
		    error);
}
Example #3
0
int main( int argc, char *argv[] )
{
  int		fd;
#if HAVE_SIGNAL_H
  struct sigaction signalaction;
#endif
#ifdef WIN32
  WSADATA wsadata;

  WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
 
  E_init();
  wack_alarm_set( PRINT | EXIT ); 
 
  Usage( argc, argv );
  Wackamole_init();

  if(Debug) {
    wack_alarm_enable_timestamp(NULL);
    wack_alarm_set( PRINT | ARPING | WACK_DEBUG | EXIT );
  }
  else {
    char pidstring[10];

    wack_alarm_set(PRINT | EXIT);
    wack_alarm_enable_syslog("wackamole");

#ifndef WIN32
    if(fork()) exit(0);
    setsid();
    if(fork()) exit(0);
#endif

    if( chdir("/") != 0 ){
      wack_alarm(PRINT,"chdir to root failed");
    }

    umask(0027);

    pid = getpid();
    fd = open(_PATH_WACKAMOLE_PIDDIR "/wackamole.pid",
	      O_WRONLY|O_CREAT|O_TRUNC, 0644);
    if(fd < 0) {
      wack_alarm(EXIT,
	    "Cannot write PID file " _PATH_WACKAMOLE_PIDDIR "/wackamole.pid");
    }
    snprintf(pidstring, 10, "%d\n", pid);
#ifdef BROKEN_SNPRINTF
    if(pidstring[9] != '\0') {
      pidstring[8] = '\n';
      pidstring[9] = '\0';
    }
#endif

    write(fd, pidstring, strlen(pidstring));
    close(fd);

#ifndef WIN32
    fd = open("/dev/null", O_RDWR);
    if(fd <= 2) {
      wack_alarm(EXIT, "Cannot open /dev/null\n");
    }
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    dup2(fd,STDIN_FILENO);
    dup2(fd,STDOUT_FILENO);
    dup2(fd,STDERR_FILENO);
    close(fd);
#endif
  }

#if HAVE_SIGNAL_H
  signalaction.sa_handler = Sig_handler;
  sigemptyset(&signalaction.sa_mask);
  signalaction.sa_flags = 0;

  if(sigaction(SIGINT, &signalaction, NULL)) {
    wack_alarm(EXIT, "An error occured while registering a SIGINT handler");
  }

  if(sigaction(SIGTERM, &signalaction, NULL)) {
    wack_alarm(EXIT, "An error occured while registering a SIGTERM handler");
  }
  if(sigaction(SIGBUS, &signalaction, NULL)) {
    wack_alarm(EXIT, "An error occured while registering a SIGBUS handler");
  }

  if(sigaction(SIGQUIT, &signalaction, NULL)) {
    wack_alarm(EXIT, "An error occured while registering a SIGQUIT handler");
  }

  if(sigaction(SIGSEGV, &signalaction, NULL)) {
    wack_alarm(EXIT, "An error occured while registering a SIGSEGV handler");
  }
#elif defined(WIN32)
  SetConsoleCtrlHandler(ConsoleEventHandlerRoutine, TRUE);
#endif

  if_initialize();
  
  /* connecting to the relevant Spread daemon, asking for group info */
  Spread_reconnect(-8);
  
  Send_local_arp_cache_repeat();
  E_handle_events();
  return -1;
}
Example #4
0
int main (int argc, char *argv[]) {
  int A,B,C,D, i, ic;
  struct interface req, myips[300];
  int state;
#ifdef WIN32
  WSADATA wsadata;

  WSAStartup(WINSOCK_VERSION, &wsadata);
#endif


  i=1;
  if(argc < 2) goto usage_error;
  if(argv[i][0] != '-')
    goto usage_error;
  
  switch(argv[i++][1]) {
  case 'r':
    state=ARPLIST;
    break;
  case 'l':
    state=LIST;
    break;
  case 'a':
    state=ADD;
    strcpy(req.ifname, argv[i++]);
    sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D);
    req.ipaddr.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D);
    sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D);
    req.bcast.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D);
    sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D);
    req.netmask.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D);
    break;
  case 'd':
    state=DELETE;
    sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D);
    req.ifname[0] = '\0';
    req.ipaddr.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D);
    break;
  case 's':
    state=SPOOF;
    strcpy(req.ifname, argv[i++]);
    sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D);
    req.ipaddr.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D);
    sscanf(argv[i++], "%d.%d.%d.%d", &A,&B,&C,&D);
    req.bcast.s_addr = htonl((A << 24) | (B << 16) | (C << 8) | D);
    break;
  usage_error:
  default:
    fprintf(stderr, "%s:\n\tUsage:\n\t\t-l\t\t\t\t\tlist interfaces\n\t\t-a <interface> <ip> <bcast> <netmask>\tAdd this VIP\n\t\t-d <IP>\t\t\t\t\tDelete this VIP\n\t\t-s interface VIP destinationIP\n", argv[0]);
    exit(-1);
  }
  

  if_initialize();
  if(state&ARPLIST) {
    arp_entry *ad, *ac;
    fprintf(stderr, "Sampling and printing local arp-cache\n");
    sample_arp_cache();
    sample_arp_cache();
    ac = ad = fetch_shared_arp_cache();
    while(ad && ad->ip) {
	struct in_addr iad;
	iad.s_addr = ad->ip;
	fprintf(stderr, "\t%s\n", inet_ntoa(iad));
	ad++;
    }
    free(ac);
  }
  if(state&ADD) {
    ic = if_up(&req);
    if(ic) {
      perror("ioctl");
      fprintf(stderr, "%s\n", if_error());
    } else {
      fprintf(stderr, "if_up: %s\t%s", req.ifname, inet_ntoa(req.ipaddr));
      fprintf(stderr, "\t%s", inet_ntoa(req.bcast));
      fprintf(stderr, "\t%s\n", inet_ntoa(req.netmask));
    }
  }
  if(state&DELETE) {
    ic = if_down(&req);
    if(ic)
      fprintf(stderr, "%s\n", if_error());
    else {
      fprintf(stderr, "if_down: %s\t%s", req.ifname, inet_ntoa(req.ipaddr));
      fprintf(stderr, "\t%s", inet_ntoa(req.bcast));
      fprintf(stderr, "\t%s\n", inet_ntoa(req.netmask));
    }
  }
  if(state&SPOOF) {
    ic = if_send_spoof_request(req.ifname,
			       req.ipaddr.s_addr, req.bcast.s_addr, NULL, 5, 0);
    if(ic)
      fprintf(stderr, "%s\n", if_error());
    else {
      fprintf(stderr, "if_spoofed: %s\t%s\n",req.ifname, inet_ntoa(req.ipaddr));
    }
  }
  if(state) {
    ic = if_list_ips(myips, 300);
    fprintf(stderr, "Found %d IPs:\n", ic);
    for(i=0; i<ic; i++) {
      fprintf(stderr, "%s\t[%02x:%02x:%02x:%02x:%02x:%02x]",
	myips[i].ifname,
	myips[i].mac[0], myips[i].mac[1], myips[i].mac[2],
	myips[i].mac[3], myips[i].mac[4], myips[i].mac[5]);
        fprintf(stderr, "\t%s", inet_ntoa(myips[i].ipaddr));
        fprintf(stderr, "\t%s", inet_ntoa(myips[i].bcast));
        fprintf(stderr, "\t%s\n", inet_ntoa(myips[i].netmask));
    }
  }
  return 0;
}