Пример #1
0
/*
 * Read from serial, when we have a packet write it to tun. No output
 * buffering, input buffered by stdio.
 */
void
serial_to_tun(FILE *inslip, int outfd)
{
    static union {
        unsigned char inbuf[2000];
    } uip;
    static unsigned int inbufptr = 0;
    int ret;
    unsigned char c;

#ifdef __linux__
    ret = fread(&c, 1, 1, inslip);

    if (ret == -1 || ret == 0) {
        err(1, "serial_to_tun: read");
    }

    goto after_fread;
#endif

    while (1) {
        if (inbufptr >= sizeof(uip.inbuf)) {
            if (timestamp) {
                stamptime();
            }

            fprintf(stderr, "*** dropping large %d byte packet\n", inbufptr);
            inbufptr = 0;
        }

        ret = fread(&c, 1, 1, inslip);
#ifdef __linux__
    after_fread:
#endif

        if (ret == -1) {
            err(1, "serial_to_tun: read");
        }

        if (ret == 0) {
            clearerr(inslip);
            return;
        }

        /*  fprintf(stderr, ".");*/
        switch (c) {
            case SLIP_END:
                if (inbufptr > 0) {
                    if (uip.inbuf[0] == '!') {
                        if (uip.inbuf[1] == 'M') {
                            /* Read gateway MAC address and autoconfigure tap0 interface */
                            char macs[24];
                            unsigned int pos = 0;

                            for (unsigned int i = 0; i < 16; i++) {
                                macs[pos++] = uip.inbuf[2 + i];

                                if ((i & 1) == 1 && i < 14) {
                                    macs[pos++] = ':';
                                }
                            }

                            if (timestamp) {
                                stamptime();
                            }

                            macs[pos] = '\0';
                            fprintf(stderr, "*** Gateway's MAC address: %s\n", macs);

                            if (timestamp) {
                                stamptime();
                            }

                            ssystem("ifconfig %s down", tundev);

                            if (timestamp) {
                                stamptime();
                            }

                            ssystem("ifconfig %s hw ether %s", tundev, &macs[6]);

                            if (timestamp) {
                                stamptime();
                            }

                            ssystem("ifconfig %s up", tundev);
                        }
                    }
                    else if (uip.inbuf[0] == '?') {
                        if (uip.inbuf[1] == 'P') {
                            /* Prefix info requested */
                            struct in6_addr addr;
                            char *s = strchr(ipaddr, '/');

                            if (s != NULL) {
                                *s = '\0';
                            }

                            inet_pton(AF_INET6, ipaddr, &addr);

                            if (timestamp) {
                                stamptime();
                            }

                            fprintf(stderr, "*** Address:%s => %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
                                    ipaddr,
                                    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(slipfd, '!');
                            slip_send(slipfd, 'P');

                            for (unsigned int i = 0; i < 8; i++) {
                                /* need to call the slip_send_char for stuffing */
                                slip_send_char(slipfd, addr.s6_addr[i]);
                            }

                            slip_send(slipfd, SLIP_END);
                        }

#define DEBUG_LINE_MARKER '\r'
                    }
                    else if (uip.inbuf[0] == DEBUG_LINE_MARKER) {
                        fwrite(uip.inbuf + 1, inbufptr - 1, 1, stdout);
                    }
                    else if (is_sensible_string(uip.inbuf, inbufptr)) {
                        if (verbose == 1) { /* strings already echoed below for verbose>1 */
                            if (timestamp) {
                                stamptime();
                            }

                            fwrite(uip.inbuf, inbufptr, 1, stdout);
                        }
                    }
                    else {
                        if (verbose > 2) {
                            if (timestamp) {
                                stamptime();
                            }

                            printf("Packet from SLIP of length %d - write TUN\n", inbufptr);

                            if (verbose > 4) {
#if WIRESHARK_IMPORT_FORMAT
                                printf("0000");

                                for (unsigned int i = 0; i < inbufptr; i++) {
                                    printf(" %02x", uip.inbuf[i]);
                                }

#else
                                printf("         ");

                                for (unsigned int i = 0; i < inbufptr; i++) {
                                    printf("%02x", uip.inbuf[i]);

                                    if ((i & 3) == 3) {
                                        printf(" ");
                                    }

                                    if ((i & 15) == 15) {
                                        printf("\n         ");
                                    }
                                }

#endif
                                printf("\n");
                            }
                        }

                        if (write(outfd, uip.inbuf, inbufptr) != inbufptr) {
                            err(1, "serial_to_tun: write");
                        }
                    }

                    inbufptr = 0;
                }

                break;

            case SLIP_ESC:
                if (fread(&c, 1, 1, inslip) != 1) {
                    clearerr(inslip);
                    /* Put ESC back and give up! */
                    ungetc(SLIP_ESC, inslip);
                    return;
                }

                switch (c) {
                    case SLIP_ESC_END:
                        c = SLIP_END;
                        break;

                    case SLIP_ESC_ESC:
                        c = SLIP_ESC;
                        break;
                }

                /* FALLTHROUGH */
            default:
                uip.inbuf[inbufptr++] = c;

                /* Echo lines as they are received for verbose=2,3,5+ */
                /* Echo all printable characters for verbose==4 */
                if ((verbose == 2) || (verbose == 3) || (verbose > 4)) {
                    if (c == '\n') {
                        if (is_sensible_string(uip.inbuf, inbufptr)) {
                            if (timestamp) {
                                stamptime();
                            }

                            fwrite(uip.inbuf, inbufptr, 1, stdout);
                            inbufptr = 0;
                        }
                    }
                }
                else if (verbose == 4) {
                    if (c == 0 || c == '\r' || c == '\n' || c == '\t' || (c >= ' ' && c <= '~')) {
                        fwrite(&c, 1, 1, stdout);

                        if (c == '\n') if (timestamp) {
                                stamptime();
                            }
                    }
                }

                break;
        }
    }
}
Пример #2
0
void
write_to_serial(int outfd, void *inbuf, int len)
{
    u_int8_t *p = inbuf;
    int i;

    if (verbose > 2) {
        if (timestamp) {
            stamptime();
        }

        printf("Packet from TUN of length %d - write SLIP\n", len);

        if (verbose > 4) {
#if WIRESHARK_IMPORT_FORMAT
            printf("0000");

            for (i = 0; i < len; i++) {
                printf(" %02x", p[i]);
            }

#else
            printf("         ");

            for (i = 0; i < len; i++) {
                printf("%02x", p[i]);

                if ((i & 3) == 3) {
                    printf(" ");
                }

                if ((i & 15) == 15) {
                    printf("\n         ");
                }
            }

#endif
            printf("\n");
        }
    }

    /* It would be ``nice'' to send a SLIP_END here but it's not
     * really necessary.
     */
    /* slip_send(outfd, SLIP_END); */

    for (i = 0; i < len; i++) {
        switch (p[i]) {
            case SLIP_END:
                slip_send(outfd, SLIP_ESC);
                slip_send(outfd, SLIP_ESC_END);
                break;

            case SLIP_ESC:
                slip_send(outfd, SLIP_ESC);
                slip_send(outfd, SLIP_ESC_ESC);
                break;

            default:
                slip_send(outfd, p[i]);
                break;
        }
    }

    slip_send(outfd, SLIP_END);
    PROGRESS("t");
}
Пример #3
0
void
slip_send_char(int fd, unsigned char c)
{
  switch(c) {
  case SLIP_END:
    slip_send(fd, SLIP_ESC);
    slip_send(fd, SLIP_ESC_END);
    break;
  case SLIP_ESC:
    slip_send(fd, SLIP_ESC);
    slip_send(fd, SLIP_ESC_ESC);
    break;
  case XON:
    if(flowcontrol_xonxoff) {
      slip_send(fd, SLIP_ESC);
      slip_send(fd, SLIP_ESC_XON);
    } else {
      slip_send(fd, c);
    }
    break;
  case XOFF:
    if(flowcontrol_xonxoff) {
      slip_send(fd, SLIP_ESC);
      slip_send(fd, SLIP_ESC_XOFF);
    } else {
      slip_send(fd, c);
    }
    break;
  default:
    slip_send(fd, c);
    break;
  }
}
Пример #4
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 ipa_enable = 0;
  int tap = 0;
  slipfd = 0;

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

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

    case 'H':
      flowcontrol=1;
      break;

    case 'X':
      flowcontrol_xonxoff=1;
      break;

    case 'L':
      timestamp=1;
      break;

    case 'M':
      devmtu=atoi(optarg);
      if(devmtu < MIN_DEVMTU) {
        devmtu = MIN_DEVMTU;
      }

    case 'P':
      showprogress=1;
      break;

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

    case 'I':
      ipa_enable = 1;
      fprintf(stderr, "Will inquire about IP address using IPA=\n");
      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");
#ifndef __APPLE__
fprintf(stderr," -B baudrate    9600,19200,38400,57600,115200 (default),230400,460800,921600\n");
#else
fprintf(stderr," -B baudrate    9600,19200,38400,57600,115200 (default),230400\n");
#endif
fprintf(stderr," -H             Hardware CTS/RTS flow control (default disabled)\n");
fprintf(stderr," -I             Inquire IP address\n");
fprintf(stderr," -X             Software XON/XOFF flow control (default disabled)\n");
fprintf(stderr," -L             Log output format (adds time stamps)\n");
fprintf(stderr," -s siodev      Serial device (default /dev/ttyUSB0)\n");
fprintf(stderr," -M             Interface MTU (default and min: 1280)\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," -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] [-H] [-L] [-s siodev] [-t tundev] [-T] [-v verbosity] [-d delay] [-a serveraddress] [-p serverport] ipaddress", prog);
  }
  ipaddr = argv[1];

  if(baudrate != -2) { /* -2: use default baudrate */
    b_rate = select_baudrate(baudrate);
    if(b_rate == 0) {
      err(1, "unknown baudrate %d", baudrate);
    }
  }

  if(*tundev == '\0') {
    /* Use default. */
    if(tap) {
      strcpy(tundev, "tap0");
    } else {
      strcpy(tundev, "tun0");
    }
  }
  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 /dev/tun");
  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);

    if(got_sigalarm && ipa_enable) {
      /* 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);
	if(ipa_enable) 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);
          slip_flushbuf(slipfd);
          if(ipa_enable) 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;
          }
        }
      }
    }
  }
}
Пример #5
0
static int net_driver_slip_send(struct net_buf *buf)
{
	NET_DBG("Sending %d bytes\n", buf->len);

	return slip_send(buf);
}
Пример #6
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();
      }
    }
  }
}
Пример #7
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);
            }
        }
    }
}
Пример #8
0
void
write_to_serial(int outfd, void *inbuf, int len)
{
    u_int8_t *p = inbuf;
    int i, ecode;
    struct ip *iphdr = inbuf;

    /*
     * Sanity checks.
     */
    ecode = check_ip(inbuf, len);

    if (ecode < 0) {
        fprintf(stderr, "tun_to_serial: drop packet %d\n", ecode);
        return;
    }

    if (iphdr->ip_id == 0 && iphdr->ip_off & IP_DF) {
        uint16_t nid = htons(ip_id++);
        iphdr->ip_id = nid;
        nid = ~nid;			/* negate */
        iphdr->ip_sum += nid;	/* add */

        if (iphdr->ip_sum < nid) {	/* 1-complement overflow? */
            iphdr->ip_sum++;
        }

        ecode = check_ip(inbuf, len);

        if (ecode < 0) {
            fprintf(stderr, "tun_to_serial: drop packet %d\n", ecode);
            return;
        }
    }

    /* It would be ``nice'' to send a SLIP_END here but it's not
     * really necessary.
     */
    /* slip_send(outfd, SLIP_END); */

    for (i = 0; i < len; i++) {
        switch (p[i]) {
            case SLIP_END:
                slip_send(outfd, SLIP_ESC);
                slip_send(outfd, SLIP_ESC_END);
                break;

            case SLIP_ESC:
                slip_send(outfd, SLIP_ESC);
                slip_send(outfd, SLIP_ESC_ESC);
                break;

            default:
                slip_send(outfd, p[i]);
                break;
        }

    }

    slip_send(outfd, SLIP_END);
    PROGRESS("t");
}
Пример #9
0
/*---------------------------------------------------------------------------*/
void
slip_init(void)
{
  setvbuf(stdout, NULL, _IOLBF, 0);     /* Line buffered output. */

  if(slip_config_host != NULL) {
    if(slip_config_port == NULL) {
      slip_config_port = "60001";
    }
    slipfd = connect_to_server(slip_config_host, slip_config_port);
    if(slipfd == -1) {
      LOG6LBR_FATAL("can't connect to %s:%s\n", slip_config_host,
          slip_config_port);
      exit(1);
    }

  } else if(slip_config_siodev != NULL) {
    if(strcmp(slip_config_siodev, "null") == 0) {
      /* Disable slip */
      return;
    }
    slipfd = devopen(slip_config_siodev, O_RDWR | O_NONBLOCK);
    if(slipfd == -1) {
      LOG6LBR_FATAL( "can't open siodev /dev/%s : %s\n", slip_config_siodev, strerror(errno));
      exit(1);
    }

  } else {
    static const char *siodevs[] = {
      "ttyUSB0", "cuaU0", "ucom0"       /* linux, fbsd6, fbsd5 */
    };
    int i;

    for(i = 0; i < 3; i++) {
      slip_config_siodev = siodevs[i];
      slipfd = devopen(slip_config_siodev, O_RDWR | O_NONBLOCK);
      if(slipfd != -1) {
        break;
      }
    }
    if(slipfd == -1) {
      LOG6LBR_FATAL("can't open siodev : %s\n", strerror(errno));
      exit(1);
    }
  }

  select_set_callback(slipfd, &slip_callback);

  if(slip_config_host != NULL) {
    LOG6LBR_INFO("SLIP opened to %s:%s\n", slip_config_host,
           slip_config_port);
  } else {
    LOG6LBR_INFO("SLIP started on /dev/%s\n", slip_config_siodev);
    stty_telos(slipfd);
  }

  timer_set(&send_delay_timer, 0);
  slip_send(slipfd, SLIP_END);
  inslip = fdopen(slipfd, "r");
  if(inslip == NULL) {
    LOG6LBR_FATAL("main: fdopen: %s\n", strerror(errno));
    exit(1);
  }
}