Exemple #1
0
void
slip_flushbuf(int fd)
{
    int n;

    if (slip_empty()) {
        return;
    }

    n = write(fd, slip_buf + slip_begin, (slip_end - slip_begin));

    if (n == -1 && errno != EAGAIN) {
        err(1, "slip_flushbuf write failed");
    }
    else if (n == -1) {
        PROGRESS("Q");      /* Outqueue is full! */
    }
    else {
        slip_begin += n;

        if (slip_begin == slip_end) {
            slip_begin = slip_end = 0;
        }
    }
}
Exemple #2
0
/*---------------------------------------------------------------------------*/
static int
set_fd(fd_set * rset, fd_set * wset)
{
  /* Anything to flush? */
  if(!slip_empty() && (send_delay == 0 || timer_expired(&send_delay_timer))) {
    FD_SET(slipfd, wset);
  }

  FD_SET(slipfd, rset);         /* Read from slip ASAP! */
  return 1;
}
Exemple #3
0
/*---------------------------------------------------------------------------*/
int
slip_set_fd(int maxfd, fd_set *rset, fd_set *wset)
{
  if(!slip_empty()) {		/* Anything to flush? */
    FD_SET(slipfd, wset);
  }

  FD_SET(slipfd, rset);	/* Read from slip ASAP! */
  if(slipfd > maxfd) maxfd = slipfd;

  return maxfd;
}
Exemple #4
0
/*---------------------------------------------------------------------------*/
void
slip_flushbuf(int fd)
{
  int n;

  if(slip_empty()) {
    return;
  }

  n = write(fd, slip_buf + slip_begin, slip_packet_end - slip_begin);

  if(n == -1 && errno != EAGAIN) {
    LOG6LBR_FATAL("slip_flushbuf::write() : %s\n", strerror(errno));
    exit(1);
  } else if(n == -1) {
    PROGRESS("Q");              /* Outqueue is full! */
  } else {
    slip_begin += n;
    if(slip_begin == slip_packet_end) {
      slip_packet_count--;
      if(slip_end > slip_packet_end) {
        memcpy(slip_buf, slip_buf + slip_packet_end,
               slip_end - slip_packet_end);
      }
      slip_end -= slip_packet_end;
      slip_begin = slip_packet_end = 0;
      if(slip_end > 0) {
        /* Find end of next slip packet */
        for(n = 1; n < slip_end; n++) {
          if(slip_buf[n] == SLIP_END) {
            slip_packet_end = n + 1;
            break;
          }
        }
        /* a delay between slip packets to avoid losing data */
        if(send_delay > 0) {
          timer_set(&send_delay_timer, send_delay);
        }
      }
    }
  }
}
Exemple #5
0
void send_commands(void)
{
	char buf[3];

	if (request_mac) {
		slip_send('?');
		slip_send('M');
		slip_send(SLIP_END);

		request_mac = 0;
		alarm(REQUEST_MAC_TIMEOUT);
	}
	/* Send our mac to the device. If it knows our address, it is not needed to change
	the MAC address of our local interface (this can be also unsupported, especially under
	Windows).
	*/
	else if(send_mac && slip_empty()){
		short i;
		PRINTF("Sending our MAC.\n");

		slip_send('!');
		slip_send('M');

		for(i=0; i < 6; i++){
			sprintf(buf,"%02X",adapter_eth_addr.addr[i]);
			slip_send(buf[0]);
			slip_send(buf[1]);
		}
		slip_send(SLIP_END);

		send_mac = false;
	}
	else if(set_sniffer_mode && slip_empty()){

		PRINTF("Setting sniffer mode to %d.\n", sniffer_mode);

		slip_send('!');
		slip_send('O');
		slip_send('S');

		if(sniffer_mode){
			slip_send('1');
		}
		else {
			slip_send('0');
		}
		slip_send(SLIP_END);

		set_sniffer_mode = 0;

	}
	else if(set_channel && slip_empty()){

		if(channel != 0){
			PRINTF("Setting channel %02d.\n", channel);

			slip_send('!');
			slip_send('O');
			slip_send('C');
			
			sprintf(buf,"%02d",channel);
			slip_send(buf[0]);
			slip_send(buf[1]);

			slip_send(SLIP_END);
		}

		set_channel = 0;

	}
    else if(send_prefix && br_prefix != NULL  && slip_empty()){

        struct in6_addr addr;
        int i;

        inet_pton(AF_INET6, br_prefix, &addr);
		if (timestamp) stamptime();
        fprintf(stderr,"*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
            br_prefix, 
            addr.s6_addr[0], addr.s6_addr[1],
            addr.s6_addr[2], addr.s6_addr[3],
            addr.s6_addr[4], addr.s6_addr[5],
            addr.s6_addr[6], addr.s6_addr[7]);
        slip_send('!');
        slip_send('P');
        for(i = 0; i < 8; i++) {
            /* need to call the slip_send_char for stuffing */
            slip_send_char(addr.s6_addr[i]);
        }
        slip_send(SLIP_END);

        send_prefix = false;

    }
}
Exemple #6
0
int
main(int argc, char **argv)
{
	int c;
	int slipfd, maxfd;
	int ret;
	fd_set rset, wset;
	FILE *inslip;
	char siodev[10] = "";
	int baudrate = -2;

	char buf[4000];
    
    prog = argv[0];

	setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */

	memset(&osVersionInfo,0,sizeof(OSVERSIONINFO));
	osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&osVersionInfo);

    while((c = getopt(argc, argv, "B:D:L:hs:c:ra:p:vtb:")) != -1) {
		switch (c) {
	case 'B':
		baudrate = atoi(optarg);
		break;

	case 'L':
		if(strncmp("0", optarg, 1) == 0) {
		  timestamp = 0;
		} else {
		  timestamp = atoi(optarg);
		  if (timestamp==0) timestamp=1;
		}
		break;

	case 's':
		if(strncmp("/dev/", optarg, 5) == 0) {
			strncpy(siodev,optarg + 5,sizeof(siodev)-1);
		}
		else if(strncmp("COM", optarg, 3) == 0) {

			int portnum;

			portnum = atoi(optarg+3);

			if(portnum == 0){
				err(1,"port number is invalid");
			}
			sprintf(siodev,"ttyS%d",portnum-1);
		}
		else {
			strncpy(siodev,optarg,sizeof(siodev)-1);
		}
		break;

	case 'c':
		channel = atoi(optarg);
		set_channel = 1;
		break;
	case 'r':
		sniffer_mode = 1;
		break;

	case 'a':
		if(autoconf == true){
			print_help();
		}
		local_ipaddr = optarg;
        if (!validIPAddr(local_ipaddr, 0)){
			if (timestamp) stamptime();
            fprintf(stderr, "Invalid IPv6 address: %s", local_ipaddr);
            exit(1);
        }
		break;

	case 'p':
		if(local_ipaddr !=NULL){
			print_help();
		}
		autoconf = true;
		ipprefix = optarg;
        if (!validIPAddr(ipprefix, 0)){
			if (timestamp) stamptime();
            fprintf(stderr, "Invalid IPv6 prefix: %s", ipprefix);
            exit(1);
        }
		break;

	case 'v':
		verbose = true;
		break;

    case 't':
		tun = true;
		break;

    case 'b':
		br_prefix = optarg;
        send_prefix = true;
        send_mac = false;
        tun = true;

        if (!validIPAddr(br_prefix, 64)){
			if (timestamp) stamptime();
            fprintf(stderr, "Invalid IPv6 64-bit prefix: %s", br_prefix);
            exit(1);
        }
        strtok(br_prefix,"/"); // Remove prefix length if it is present.
		break;

	case '?':
	case 'h':
	default:
		print_help();
		break;
		}
	}
	argc -= (optind - 1);
	argv += (optind - 1);

	if(argc != 2 || *siodev == '\0') {
		print_help();
	}

    if(autoconf == true && br_prefix != NULL){
		if (timestamp) stamptime();
        fprintf(stderr, "-p and -b options cannot be used together.\r\n");
        print_help();
    }

	sscanf(argv[1],"%2X-%2X-%2X-%2X-%2X-%2X",
		(int *)&adapter_eth_addr.addr[0],(int *)&adapter_eth_addr.addr[1],
        (int *)&adapter_eth_addr.addr[2],(int *)&adapter_eth_addr.addr[3],
        (int *)&adapter_eth_addr.addr[4],(int *)&adapter_eth_addr.addr[5]);
	if_name = wpcap_start(&adapter_eth_addr, verbose);

	if(local_ipaddr!=NULL){
		addAddress(if_name, local_ipaddr);
	}

	switch(baudrate) {
  case -2:
	  break;			/* Use default. */
  case 9600:
	  b_rate = B9600;
	  break;
  case 19200:
	  b_rate = B19200;
	  break;
  case 38400:
	  b_rate = B38400;
	  break;
  case 57600:
	  b_rate = B57600;
	  break;
  case 115200:
	  b_rate = B115200;
	  break;
  case 230400:
	  b_rate = B230400;
	  break;
  case 460800:
	  b_rate = B460800;
	  break;
  case 921600:
	  b_rate = B921600;
	  break;
  default:
	  err(1, "unknown baudrate %d", baudrate);
	  break;
	}


	slipfd = devopen(siodev, O_RDWR | O_NONBLOCK | O_NOCTTY | O_NDELAY | O_DIRECT | O_SYNC );
	if(slipfd == -1) {
		err(1, "can't open siodev ``/dev/%s''", siodev);
	}
	if (timestamp) stamptime();
	fprintf(stderr, "wpcapslip6 started on ``/dev/%s''\n", siodev);
	stty_telos(slipfd);
	slip_send(SLIP_END);
	inslip = fdopen(slipfd, "r");
	if(inslip == NULL) err(1, "main: fdopen");


	atexit(cleanup);
	signal(SIGHUP, sigcleanup);
	signal(SIGTERM, sigcleanup);
	signal(SIGINT, sigcleanup);
	signal(SIGALRM, sigalarm);

	/* Request mac address from gateway. It may be useful for setting the best 
	IPv6 address of the local interface. */


	while(1) {
		maxfd = 0;
		FD_ZERO(&rset);
		FD_ZERO(&wset);

		send_commands();		

		if(!slip_empty()) {		/* Anything to flush? */
			FD_SET(slipfd, &wset);
		}

		FD_SET(slipfd, &rset);	/* Read from slip ASAP! */
		if(slipfd > maxfd) maxfd = slipfd;
#ifdef WITH_STDIN
		FD_SET(STDIN_FILENO, &rset);  /* Read from stdin too. */
		if(STDIN_FILENO > maxfd) maxfd = STDIN_FILENO;   /* This would not be necessary, since we know STDIN_FILENO is 0. */
#endif

		if(slip_empty()) {
			char *pbuf = buf;

			ret = wpcap_poll(pbuf);
			if( ret > 0 ){
				struct uip_eth_hdr * eth_hdr = (struct uip_eth_hdr *)pbuf;

				if(eth_hdr->type == htons(UIP_ETHTYPE_IPV6)){
					// We forward only IPv6 packet.
                    
                    if(tun){
                        // Cut away ethernet header.
                        pbuf += sizeof(struct uip_eth_hdr);
                        ret -= sizeof(struct uip_eth_hdr);
                    }

					write_to_serial(pbuf, ret);
					/*print_packet(pbuf, ret);*/
					slip_flushbuf(slipfd);
				}
			}
		}
		{
			struct timeval tv;
			tv.tv_sec = 0;
			tv.tv_usec = 10;
			ret = select(maxfd + 1, &rset, &wset, NULL, &tv);
		}
		if(ret == -1 && errno != EINTR && errno != EAGAIN) {
			err(1, "select");
		}
		else if(ret > 0) {
			if(FD_ISSET(slipfd, &rset)) {
				/* printf("serial_to_wpcap\n"); */
				serial_to_wpcap(inslip);
				/*	printf("End of serial_to_wpcap\n");*/
			}  

			if(FD_ISSET(slipfd, &wset)) {
				slip_flushbuf(slipfd);				
			}
#ifdef WITH_STDIN
			if(FD_ISSET(STDIN_FILENO, &rset)) {
				char inbuf;
				if(fread(&inbuf,1,1,stdin)){
					if(inbuf=='q'){
						exit(0);
					}
				}
			}
#endif
		}
	}
}
Exemple #7
0
	int
main(int argc, char **argv)
{
	int c;
	int tunfd, maxfd;
	int ret;
	fd_set rset, wset;
	FILE *inslip;
	const char *siodev = NULL;
	const char *host = NULL;
	const char *port = NULL;
	const char *prog;
	int baudrate = -2;
	int tap = 0;
	slipfd = 0;

	prog = argv[0];
	setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */

	while((c = getopt(argc, argv, "B:D:Lhs:t:v::d::a:p:T")) != -1) {
		switch(c) {
			case 'B':
				baudrate = atoi(optarg);
				break;

			case 'L':
				timestamp=1;
				break;

			case 's':
				if(strncmp("/dev/", optarg, 5) == 0) {
					siodev = optarg + 5;
				} else {
					siodev = optarg;
				}
				break;

			case 't':
				if(strncmp("/dev/", optarg, 5) == 0) {
					strncpy(tundev, optarg + 5, sizeof(tundev));
				} else {
					strncpy(tundev, optarg, sizeof(tundev));
				}
				break;

			case 'a':
				host = optarg;
				break;

			case 'p':
				port = optarg;
				break;

			case 'd':
				basedelay = 10;
				if (optarg) basedelay = atoi(optarg);
				break;

			case 'v':
				verbose = 2;
				if (optarg) verbose = atoi(optarg);
				break;

			case 'T':
				tap = 1;
				break;

			case '?':
			case 'h':
			default:
				fprintf(stderr,"usage:  %s [options] ipaddress\n", prog);
				fprintf(stderr,"example: tunslip6 -L -v2 -s ttyUSB1 aaaa::1/64\n");
				fprintf(stderr,"Options are:\n");
				fprintf(stderr," -B baudrate    9600,19200,38400,57600,115200 (default)\n");
				fprintf(stderr," -L             Log output format (adds time stamps)\n");
				fprintf(stderr," -s siodev      Serial device (default /dev/ttyUSB0)\n");
				fprintf(stderr," -T             Make tap interface (default is tun interface)\n");
				//fprintf(stderr," -t tundev      Name of interface (default tap0 or tun0)\n");
				fprintf(stderr," -t tundev      Name of interface\n");
				fprintf(stderr," -v[level]      Verbosity level\n");
				fprintf(stderr,"    -v0         No messages\n");
				fprintf(stderr,"    -v1         Encapsulated SLIP debug messages (default)\n");
				fprintf(stderr,"    -v2         Printable strings after they are received\n");
				fprintf(stderr,"    -v3         Printable strings and SLIP packet notifications\n");
				fprintf(stderr,"    -v4         All printable characters as they are received\n");
				fprintf(stderr,"    -v5         All SLIP packets in hex\n");
				fprintf(stderr,"    -v          Equivalent to -v3\n");
				fprintf(stderr," -d[basedelay]  Minimum delay between outgoing SLIP packets.\n");
				fprintf(stderr,"                Actual delay is basedelay*(#6LowPAN fragments) milliseconds.\n");
				fprintf(stderr,"                -d is equivalent to -d10.\n");
				fprintf(stderr," -a serveraddr  \n");
				fprintf(stderr," -p serverport  \n");
				exit(1);
				break;
		}
	}
	argc -= (optind - 1);
	argv += (optind - 1);

	if(argc != 2 && argc != 3) {
		err(1, "usage: %s [-B baudrate] [-L] [-s siodev] [-t tundev] [-T] [-v verbosity] [-d delay] [-a serveraddress] [-p serverport] ipaddress", prog);
	}
	ipaddr = argv[1];

	switch(baudrate) {
		case -2:
			break;			/* Use default. */
		case 9600:
			b_rate = B9600;
			break;
		case 19200:
			b_rate = B19200;
			break;
		case 38400:
			b_rate = B38400;
			break;
		case 57600:
			b_rate = B57600;
			break;
		case 115200:
			b_rate = B115200;
			break;
		default:
			err(1, "unknown baudrate %d", baudrate);
			break;
	}

#if 0
	if(*tundev == '\0') {
		/* Use default. */
		if(tap) {
			strcpy(tundev, "tap0");
		} else {
			strcpy(tundev, "tun0");
		}
	}
#endif
	if(host != NULL) {
		struct addrinfo hints, *servinfo, *p;
		int rv;
		char s[INET6_ADDRSTRLEN];

		if(port == NULL) {
			port = "60001";
		}

		memset(&hints, 0, sizeof hints);
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;

		if((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
			err(1, "getaddrinfo: %s", gai_strerror(rv));
		}

		/* loop through all the results and connect to the first we can */
		for(p = servinfo; p != NULL; p = p->ai_next) {
			if((slipfd = socket(p->ai_family, p->ai_socktype,
							p->ai_protocol)) == -1) {
				perror("client: socket");
				continue;
			}

			if(connect(slipfd, p->ai_addr, p->ai_addrlen) == -1) {
				close(slipfd);
				perror("client: connect");
				continue;
			}
			break;
		}

		if(p == NULL) {
			err(1, "can't connect to ``%s:%s''", host, port);
		}

		fcntl(slipfd, F_SETFL, O_NONBLOCK);

		inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
				s, sizeof(s));
		fprintf(stderr, "slip connected to ``%s:%s''\n", s, port);

		/* all done with this structure */
		freeaddrinfo(servinfo);

	} else {
		if(siodev != NULL) {
			slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
			if(slipfd == -1) {
				err(1, "can't open siodev ``/dev/%s''", siodev);
			}
		} else {
			static const char *siodevs[] = {
				"ttyUSB0", "cuaU0", "ucom0" /* linux, fbsd6, fbsd5 */
			};
			int i;
			for(i = 0; i < 3; i++) {
				siodev = siodevs[i];
				slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
				if(slipfd != -1) {
					break;
				}
			}
			if(slipfd == -1) {
				err(1, "can't open siodev");
			}
		}
		if (timestamp) stamptime();
		fprintf(stderr, "********SLIP started on ``/dev/%s''\n", siodev);
		stty_telos(slipfd);
	}
	slip_send(slipfd, SLIP_END);
	inslip = fdopen(slipfd, "r");
	if(inslip == NULL) err(1, "main: fdopen");

	tunfd = tun_alloc(tundev, tap);
	if(tunfd == -1) err(1, "main: open");
	if (timestamp) stamptime();
	fprintf(stderr, "opened %s device ``/dev/%s''\n",
			tap ? "tap" : "tun", tundev);

	atexit(cleanup);
	signal(SIGHUP, sigcleanup);
	signal(SIGTERM, sigcleanup);
	signal(SIGINT, sigcleanup);
	signal(SIGALRM, sigalarm);
	ifconf(tundev, ipaddr);

	while(1) {
		maxfd = 0;
		FD_ZERO(&rset);
		FD_ZERO(&wset);

		/* do not send IPA all the time... - add get MAC later... */
		/*     if(got_sigalarm) { */
		/*       /\* Send "?IPA". *\/ */
		/*       slip_send(slipfd, '?'); */
		/*       slip_send(slipfd, 'I'); */
		/*       slip_send(slipfd, 'P'); */
		/*       slip_send(slipfd, 'A'); */
		/*       slip_send(slipfd, SLIP_END); */
		/*       got_sigalarm = 0; */
		/*     } */

		if(!slip_empty()) {		/* Anything to flush? */
			FD_SET(slipfd, &wset);
		}

		FD_SET(slipfd, &rset);	/* Read from slip ASAP! */
		if(slipfd > maxfd) maxfd = slipfd;

		/* We only have one packet at a time queued for slip output. */
		if(slip_empty()) {
			FD_SET(tunfd, &rset);
			if(tunfd > maxfd) maxfd = tunfd;
		}

		ret = select(maxfd + 1, &rset, &wset, NULL, NULL);
		if(ret == -1 && errno != EINTR) {
			err(1, "select");
		} else if(ret > 0) {
			if(FD_ISSET(slipfd, &rset)) {
				serial_to_tun(inslip, tunfd);
			}

			if(FD_ISSET(slipfd, &wset)) {
				slip_flushbuf(slipfd);
				sigalarm_reset();
			}

			/* Optional delay between outgoing packets */
			/* Base delay times number of 6lowpan fragments to be sent */
			if(delaymsec) {
				struct timeval tv;
				int dmsec;
				gettimeofday(&tv, NULL) ;
				dmsec=(tv.tv_sec-delaystartsec)*1000+tv.tv_usec/1000-delaystartmsec;
				if(dmsec<0) delaymsec=0;
				if(dmsec>delaymsec) delaymsec=0;
			}

			if(delaymsec==0) {
				//int size;

				if(slip_empty() && FD_ISSET(tunfd, &rset)) {
					//size = tun_to_serial(tunfd, slipfd);
					tun_to_serial(tunfd, slipfd);
					slip_flushbuf(slipfd);
					sigalarm_reset();

					if(basedelay) {
						struct timeval tv;
						gettimeofday(&tv, NULL) ;
						//         delaymsec=basedelay*(1+(size/120));//multiply by # of 6lowpan packets?
						delaymsec=basedelay;
						delaystartsec =tv.tv_sec;
						delaystartmsec=tv.tv_usec/1000;
					}
				}
			}
		}
	}
}
Exemple #8
0
int main(int argc, char **argv)
{
	int c;
	int tunfd, slipfd, maxfd;
	int ret;
	fd_set rset, wset;

	unsigned short dst_port = DST_PORT + 1;

	ip_id = getpid() * time(NULL);

	setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */

	while ((c = getopt(argc, argv, "n:t:")) != -1) {
		switch (c) {
		case 'n':
			dst_port = DST_PORT + atoi(optarg);
			break;
		case 't':
			if (strncmp("/dev/", optarg, 5) == 0) {
				strcpy(tundev, optarg + 5);
			} else {
				strcpy(tundev, optarg);
			}
			break;

		case '?':
		case 'h':
		default:
			err(1,USAGE_STRING);
			break;
		}
	}
	argc -= (optind - 1);
	argv += (optind - 1);

	if (argc != 1) {
		err(1, USAGE_STRING);
	}
	ipaddr = "172.16.0.0";
	netmask = "255.255.0.0";
	circuit_addr = inet_addr(ipaddr);
	netaddr = inet_addr(ipaddr) & inet_addr(netmask);

	slipfd = devopen(dst_port);
	if (slipfd == -1) {
		err(1, "can't open port %u", dst_port);
	}

	fprintf(stderr, "slip sending to port %u\n", dst_port);
	stty_telos(slipfd);
	slip_send(slipfd, SLIP_END);

	tunfd = tun_alloc(tundev);
	if (tunfd == -1)
		err(1, "main: open");
	fprintf(stderr, "opened device ``/dev/%s''\n", tundev);

	atexit(cleanup);
	signal(SIGHUP, sigcleanup);
	signal(SIGTERM, sigcleanup);
	signal(SIGINT, sigcleanup);
	signal(SIGALRM, sigalarm);
	ifconf(tundev, ipaddr, netmask);

	while (1) {
		maxfd = 0;
		FD_ZERO(&rset);
		FD_ZERO(&wset);

		if (got_sigalarm) {
			/* Send "?IPA". */
			slip_send(slipfd, '?');
			slip_send(slipfd, 'I');
			slip_send(slipfd, 'P');
			slip_send(slipfd, 'A');
			slip_send(slipfd, SLIP_END);
			got_sigalarm = 0;
		}

		if (!slip_empty()) { /* Anything to flush? */
			FD_SET(slipfd, &wset);
		}

		FD_SET(slipfd, &rset); /* Read from slip ASAP! */
		if (slipfd > maxfd)
			maxfd = slipfd;

		/* We only have one packet at a time queued for slip output. */
		if (slip_empty()) {
			FD_SET(tunfd, &rset);
			if (tunfd > maxfd)
				maxfd = tunfd;
			if (dhsock != -1) {
				FD_SET(dhsock, &rset);
				if (dhsock > maxfd)
					maxfd = dhsock;
			}
		}

		ret = select(maxfd + 1, &rset, &wset, NULL, NULL);
		if (ret == -1 && errno != EINTR) {
			err(1, "select");
		} else if (ret > 0) {
			if (FD_ISSET(slipfd, &rset)) {
				serial_to_tun(slipfd, tunfd);
			}

			if (FD_ISSET(slipfd, &wset)) {
				slip_flushbuf(slipfd);
				sigalarm_reset();
			}

			if (slip_empty() && FD_ISSET(tunfd, &rset)) {
				tun_to_serial(tunfd, slipfd);
				slip_flushbuf(slipfd);
				sigalarm_reset();
			}

			if (dhsock != -1 && slip_empty() && FD_ISSET(dhsock, &rset)) {
				relay_dhcp_to_client(slipfd); ///  ####  ////
				slip_flushbuf(slipfd);
			}
		}
	}
}
Exemple #9
0
int
main(int argc, char **argv)
{
  int c;
  int tunfd, slipfd, maxfd;
  int ret;
  fd_set rset, wset;
  FILE *inslip;
  const char *siodev = NULL;
  int baudrate = -2;
  request_mac = 1;
  setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */

  while((c = getopt(argc, argv, "B:D:hs:t:")) != -1) {
    switch (c) {
    case 'B':
      baudrate = atoi(optarg);
      break;

    case 's':
      if(strncmp("/dev/", optarg, 5) == 0) {
	siodev = optarg + 5;
      } else {
	siodev = optarg;
      }
      break;

    case 't':
      if(strncmp("/dev/", optarg, 5) == 0) {
	strcpy(tundev, optarg + 5);
      } else {
	strcpy(tundev, optarg);
      }
      break;

    case '?':
    case 'h':
    default:
      errx(1, USAGE_STRING);
      break;
    }
  }
  argc -= (optind - 1);
  argv += (optind - 1);

  if(argc != 3 && argc != 4) {
    errx(1, USAGE_STRING);
  }
  ipaddr = argv[1];
  netmask = argv[2];
  circuit_addr = inet_addr(ipaddr);
  netaddr = inet_addr(ipaddr) & inet_addr(netmask);

  switch(baudrate) {
  case -2:
    break;			/* Use default. */
  case 9600:
    b_rate = B9600;
    break;
  case 19200:
    b_rate = B19200;
    break;
  case 38400:
    b_rate = B38400;
    break;
  case 57600:
    b_rate = B57600;
    break;
  case 115200:
    b_rate = B115200;
    break;
  default:
    err(1, "unknown baudrate %d", baudrate);
    break;
  }


  if(siodev != NULL) {
      slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
      if(slipfd == -1) {
	err(1, "can't open siodev ``/dev/%s''", siodev);
      }
  } else {
    static const char *siodevs[] = {
      "ttyUSB0", "cuaU0", "ucom0" /* linux, fbsd6, fbsd5 */
    };
    int i;
    for(i = 0; i < 3; i++) {
      siodev = siodevs[i];
      slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
      if (slipfd != -1)
	break;
    }
    if(slipfd == -1) {
      err(1, "can't open siodev");
    }
  }
  fprintf(stderr, "slip started on ``/dev/%s''\n", siodev);
  stty_telos(slipfd);
  slip_send(slipfd, SLIP_END);
  inslip = fdopen(slipfd, "r");
  if(inslip == NULL) err(1, "main: fdopen");

  tunfd = tun_alloc(tundev);
  printf("opening: %s", tundev);
  if(tunfd == -1) err(1, "main: open");
  fprintf(stderr, "opened device ``/dev/%s''\n", tundev);

  atexit(cleanup);
  signal(SIGHUP, sigcleanup);
  signal(SIGTERM, sigcleanup);
  signal(SIGINT, sigcleanup);
  signal(SIGALRM, sigalarm);
  ifconf(tundev, ipaddr, netmask);

  while(1) {
    maxfd = 0;
    FD_ZERO(&rset);
    FD_ZERO(&wset);

    /* request mac address from gateway node for autoconfiguration of
       ethernet interface tap0 */
    if (request_mac) {
      slip_send(slipfd, '?');
      slip_send(slipfd, 'M');
      slip_send(slipfd, SLIP_END);
      request_mac = 0;
    }

    if(got_sigalarm) {
      /* Send "?IPA". */
      slip_send(slipfd, '?');
      slip_send(slipfd, 'I');
      slip_send(slipfd, 'P');
      slip_send(slipfd, 'A');
      slip_send(slipfd, SLIP_END);
      got_sigalarm = 0;
    }

    if(!slip_empty()) {		/* Anything to flush? */
      FD_SET(slipfd, &wset);
    }

    FD_SET(slipfd, &rset);	/* Read from slip ASAP! */
    if(slipfd > maxfd) maxfd = slipfd;

    /* We only have one packet at a time queued for slip output. */
    if(slip_empty()) {
      FD_SET(tunfd, &rset);
      if(tunfd > maxfd) maxfd = tunfd;
    }

    ret = select(maxfd + 1, &rset, &wset, NULL, NULL);
    if(ret == -1 && errno != EINTR) {
      err(1, "select");
    } else if(ret > 0) {
      if(FD_ISSET(slipfd, &rset)) {
        serial_to_tun(inslip, tunfd);
      }

      if(FD_ISSET(slipfd, &wset)) {
	slip_flushbuf(slipfd);
	sigalarm_reset();
      }

      if(slip_empty() && FD_ISSET(tunfd, &rset)) {
        tun_to_serial(tunfd, slipfd);
	slip_flushbuf(slipfd);
	sigalarm_reset();
      }
    }
  }
}
Exemple #10
0
int
main(int argc, char **argv)
{
    int c;
    int tunfd, slipfd, maxfd;
    int ret;
    fd_set rset, wset;
    FILE *inslip;
    const char *siodev = NULL;
    const char *dhcp_server = NULL;
    u_int16_t myport = BOOTPS, dhport = BOOTPS;
    int baudrate = -2;

    ip_id = getpid() * time(NULL);

    setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */

    while ((c = getopt(argc, argv, "B:D:hs:t:")) != -1) {
        switch (c) {
            case 'B':
                baudrate = atoi(optarg);
                break;

            case 'D':
                dhcp_server = optarg;
                break;

            case 's':
                if (strncmp("/dev/", optarg, 5) == 0) {
                    siodev = optarg + 5;
                }
                else {
                    siodev = optarg;
                }

                break;

            case 't':
                if (strncmp("/dev/", optarg, 5) == 0) {
                    strcpy(tundev, optarg + 5);
                }
                else {
                    strcpy(tundev, optarg);
                }

                break;

            case '?':
            case 'h':
            default:
                err(1, "usage: tunslip [-B baudrate] [-s siodev] [-t tundev] [-D dhcp-server] ipaddress netmask [dhcp-server]");
                break;
        }
    }

    argc -= (optind - 1);
    argv += (optind - 1);

    if (argc != 3 && argc != 4) {
        err(1, "usage: tunslip [-s siodev] [-t tundev] [-D dhcp-server] ipaddress netmask [dhcp-server]");
    }

    ipaddr = argv[1];
    netmask = argv[2];
    circuit_addr = inet_addr(ipaddr);
    netaddr = inet_addr(ipaddr) & inet_addr(netmask);

    switch (baudrate) {
        case -2:
            break;			/* Use default. */

        case 9600:
            b_rate = B9600;
            break;

        case 19200:
            b_rate = B19200;
            break;

        case 38400:
            b_rate = B38400;
            break;

        case 57600:
            b_rate = B57600;
            break;

        case 115200:
            b_rate = B115200;
            break;

        default:
            err(1, "unknown baudrate %d", baudrate);
            break;
    }

    /*
     * Set up DHCP relay agent socket and find the address of this relay
     * agent.
     */
    if (argc == 4) {
        dhcp_server = argv[3];
    }

    if (dhcp_server != NULL) {
        struct sockaddr_in myaddr;
        socklen_t len;
        in_addr_t a;

        if (strchr(dhcp_server, ':') != NULL) {
            dhport = atoi(strchr(dhcp_server, ':') + 1);
            myport = dhport + 1;
            *strchr(dhcp_server, ':') = '\0';
        }

        a = inet_addr(dhcp_server);

        if (a == -1) {
            err(1, "illegal dhcp-server address");
        }

#ifndef linux
        dhaddr.sin_len = sizeof(dhaddr);
#endif
        dhaddr.sin_family = AF_INET;
        dhaddr.sin_port = htons(dhport);
        dhaddr.sin_addr.s_addr = a;

        dhsock = socket(AF_INET, SOCK_DGRAM, 0);

        if (dhsock < 0) {
            err(1, "socket");
        }

        memset(&myaddr, 0x0, sizeof(myaddr));
#ifndef linux
        myaddr.sin_len = sizeof(myaddr);
#endif
        myaddr.sin_family = AF_INET;
        myaddr.sin_addr.s_addr = INADDR_ANY;
        myaddr.sin_port = htons(myport);

        if (bind(dhsock, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
            err(1, "bind dhcp-relay");
        }

        if (connect(dhsock, (struct sockaddr *)&dhaddr, sizeof(dhaddr)) < 0) {
            err(1, "connect to dhcp-server");
        }

        len = sizeof(myaddr);

        if (getsockname(dhsock, (struct sockaddr *)&myaddr, &len) < 0) {
            err(1, "getsockname dhsock");
        }

        giaddr = myaddr.sin_addr.s_addr;

        /*
         * Don't want connected socket.
         */
        close(dhsock);
        dhsock = socket(AF_INET, SOCK_DGRAM, 0);

        if (dhsock < 0) {
            err(1, "socket");
        }

        myaddr.sin_family = AF_INET;
        myaddr.sin_addr.s_addr = INADDR_ANY;
        myaddr.sin_port = htons(myport);

        if (bind(dhsock, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
            err(1, "bind dhcp-relay");
        }

        fprintf(stderr, "DHCP server at %s:%d\n", dhcp_server, dhport);
    }

    if (siodev != NULL) {
        slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);

        if (slipfd == -1) {
            err(1, "can't open siodev ``/dev/%s''", siodev);
        }
    }
    else {
        static const char *siodevs[] = {
            "ttyUSB0", "cuaU0", "ucom0" /* linux, fbsd6, fbsd5 */
        };
        int i;

        for (i = 0; i < 3; i++) {
            siodev = siodevs[i];
            slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);

            if (slipfd != -1) {
                break;
            }
        }

        if (slipfd == -1) {
            err(1, "can't open siodev");
        }
    }

    fprintf(stderr, "slip started on ``/dev/%s''\n", siodev);
    stty_telos(slipfd);
    slip_send(slipfd, SLIP_END);
    inslip = fdopen(slipfd, "r");

    if (inslip == NULL) {
        err(1, "main: fdopen");
    }

    tunfd = tun_alloc(tundev);

    if (tunfd == -1) {
        err(1, "main: open");
    }

    fprintf(stderr, "opened device ``/dev/%s''\n", tundev);

    atexit(cleanup);
    signal(SIGHUP, sigcleanup);
    signal(SIGTERM, sigcleanup);
    signal(SIGINT, sigcleanup);
    signal(SIGALRM, sigalarm);
    ifconf(tundev, ipaddr, netmask);

    while (1) {
        maxfd = 0;
        FD_ZERO(&rset);
        FD_ZERO(&wset);

        if (got_sigalarm) {
            /* Send "?IPA". */
            slip_send(slipfd, '?');
            slip_send(slipfd, 'I');
            slip_send(slipfd, 'P');
            slip_send(slipfd, 'A');
            slip_send(slipfd, SLIP_END);
            got_sigalarm = 0;
        }

        if (!slip_empty()) {		/* Anything to flush? */
            FD_SET(slipfd, &wset);
        }

        FD_SET(slipfd, &rset);	/* Read from slip ASAP! */

        if (slipfd > maxfd) {
            maxfd = slipfd;
        }

        /* We only have one packet at a time queued for slip output. */
        if (slip_empty()) {
            FD_SET(tunfd, &rset);

            if (tunfd > maxfd) {
                maxfd = tunfd;
            }

            if (dhsock != -1) {
                FD_SET(dhsock, &rset);

                if (dhsock > maxfd) {
                    maxfd = dhsock;
                }
            }
        }

        ret = select(maxfd + 1, &rset, &wset, NULL, NULL);

        if (ret == -1 && errno != EINTR) {
            err(1, "select");
        }
        else if (ret > 0) {
            if (FD_ISSET(slipfd, &rset)) {
                serial_to_tun(inslip, tunfd);
            }

            if (FD_ISSET(slipfd, &wset)) {
                slip_flushbuf(slipfd);
                sigalarm_reset();
            }

            if (slip_empty() && FD_ISSET(tunfd, &rset)) {
                tun_to_serial(tunfd, slipfd);
                slip_flushbuf(slipfd);
                sigalarm_reset();
            }

            if (dhsock != -1 && slip_empty() && FD_ISSET(dhsock, &rset)) {
                relay_dhcp_to_client(slipfd);
                slip_flushbuf(slipfd);
            }
        }
    }
}