Added option to connect to server instead of serial port
This commit is contained in:
parent
4aba60ad25
commit
99b2dd8ef7
135
tools/tunslip6.c
135
tools/tunslip6.c
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, Adam Dunkels.
|
* Copyright (c) 2001, Adam Dunkels.
|
||||||
* Copyright (c) 2009, 2010 Joakim Eriksson, Niclas Finne.
|
* Copyright (c) 2009, 2010 Joakim Eriksson, Niclas Finne, Dogan Yazar.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the uIP TCP/IP stack.
|
* This file is part of the uIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* $Id: tunslip6.c,v 1.2 2010/04/16 12:39:46 joxe Exp $
|
* $Id: tunslip6.c,v 1.3 2010/05/07 12:22:41 nifi Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
|
||||||
|
@ -62,7 +63,7 @@ void write_to_serial(int outfd, void *inbuf, int len);
|
||||||
//#define PROGRESS(s) fprintf(stderr, s)
|
//#define PROGRESS(s) fprintf(stderr, s)
|
||||||
#define PROGRESS(s) do { } while (0)
|
#define PROGRESS(s) do { } while (0)
|
||||||
|
|
||||||
char tundev[32] = { "tun0" };
|
char tundev[32] = { "" };
|
||||||
|
|
||||||
int
|
int
|
||||||
ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
|
ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
|
||||||
|
@ -86,6 +87,16 @@ ssystem(const char *fmt, ...)
|
||||||
#define SLIP_ESC_ESC 0335
|
#define SLIP_ESC_ESC 0335
|
||||||
|
|
||||||
|
|
||||||
|
/* get sockaddr, IPv4 or IPv6: */
|
||||||
|
void *
|
||||||
|
get_in_addr(struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
if(sa->sa_family == AF_INET) {
|
||||||
|
return &(((struct sockaddr_in*)sa)->sin_addr);
|
||||||
|
}
|
||||||
|
return &(((struct sockaddr_in6*)sa)->sin6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
is_sensible_string(const unsigned char *s, int len)
|
is_sensible_string(const unsigned char *s, int len)
|
||||||
{
|
{
|
||||||
|
@ -124,6 +135,7 @@ serial_to_tun(FILE *inslip, int outfd)
|
||||||
read_more:
|
read_more:
|
||||||
if(inbufptr >= sizeof(uip.inbuf)) {
|
if(inbufptr >= sizeof(uip.inbuf)) {
|
||||||
inbufptr = 0;
|
inbufptr = 0;
|
||||||
|
fprintf(stderr, "*** dropping too large packet\n");
|
||||||
}
|
}
|
||||||
ret = fread(&c, 1, 1, inslip);
|
ret = fread(&c, 1, 1, inslip);
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
|
@ -135,21 +147,19 @@ serial_to_tun(FILE *inslip, int outfd)
|
||||||
if(ret == 0) {
|
if(ret == 0) {
|
||||||
clearerr(inslip);
|
clearerr(inslip);
|
||||||
return;
|
return;
|
||||||
fprintf(stderr, "serial_to_tun: EOF\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
/* fprintf(stderr, ".");*/
|
/* fprintf(stderr, ".");*/
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case SLIP_END:
|
case SLIP_END:
|
||||||
if(inbufptr > 0) {
|
if(inbufptr > 0) {
|
||||||
if(uip.inbuf[0] == '!') {
|
if(uip.inbuf[0] == '!') {
|
||||||
if (uip.inbuf[1] == 'M') {
|
if(uip.inbuf[1] == 'M') {
|
||||||
/* Read gateway MAC address and autoconfigure tap0 interface */
|
/* Read gateway MAC address and autoconfigure tap0 interface */
|
||||||
char macs[24];
|
char macs[24];
|
||||||
int i, pos;
|
int i, pos;
|
||||||
for(i = 0, pos = 0; i < 16; i++) {
|
for(i = 0, pos = 0; i < 16; i++) {
|
||||||
macs[pos++] = uip.inbuf[2 + i];
|
macs[pos++] = uip.inbuf[2 + i];
|
||||||
if ((i & 1) == 1 && i < 14) {
|
if((i & 1) == 1 && i < 14) {
|
||||||
macs[pos++] = ':';
|
macs[pos++] = ':';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,7 +176,7 @@ serial_to_tun(FILE *inslip, int outfd)
|
||||||
} else if(is_sensible_string(uip.inbuf, inbufptr)) {
|
} else if(is_sensible_string(uip.inbuf, inbufptr)) {
|
||||||
fwrite(uip.inbuf, inbufptr, 1, stdout);
|
fwrite(uip.inbuf, inbufptr, 1, stdout);
|
||||||
} else {
|
} else {
|
||||||
if (verbose) printf("Writing to tun len: %d\n", inbufptr);
|
if(verbose) printf("Writing to tun len: %d\n", inbufptr);
|
||||||
if(write(outfd, uip.inbuf, inbufptr) != inbufptr) {
|
if(write(outfd, uip.inbuf, inbufptr) != inbufptr) {
|
||||||
err(1, "serial_to_tun: write");
|
err(1, "serial_to_tun: write");
|
||||||
}
|
}
|
||||||
|
@ -206,8 +216,9 @@ int slip_end, slip_begin;
|
||||||
void
|
void
|
||||||
slip_send(int fd, unsigned char c)
|
slip_send(int fd, unsigned char c)
|
||||||
{
|
{
|
||||||
if (slip_end >= sizeof(slip_buf))
|
if(slip_end >= sizeof(slip_buf)) {
|
||||||
err(1, "slip_send overflow");
|
err(1, "slip_send overflow");
|
||||||
|
}
|
||||||
slip_buf[slip_end] = c;
|
slip_buf[slip_end] = c;
|
||||||
slip_end++;
|
slip_end++;
|
||||||
}
|
}
|
||||||
|
@ -223,8 +234,9 @@ slip_flushbuf(int fd)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (slip_empty())
|
if(slip_empty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
n = write(fd, slip_buf + slip_begin, (slip_end - slip_begin));
|
n = write(fd, slip_buf + slip_begin, (slip_end - slip_begin));
|
||||||
|
|
||||||
|
@ -244,14 +256,15 @@ void
|
||||||
write_to_serial(int outfd, void *inbuf, int len)
|
write_to_serial(int outfd, void *inbuf, int len)
|
||||||
{
|
{
|
||||||
u_int8_t *p = inbuf;
|
u_int8_t *p = inbuf;
|
||||||
int i, ecode;
|
int i;
|
||||||
|
|
||||||
if (verbose) {
|
if(verbose) {
|
||||||
printf("Got packet of length %d - write SLIP\n", len);
|
printf("Got packet of length %d - write SLIP\n", len);
|
||||||
for(i = 0; i < len; i++) {
|
for(i = 0; i < len; i++) {
|
||||||
printf("%02x", p[i]);
|
printf("%02x", p[i]);
|
||||||
if((i & 3) == 3)
|
if((i & 3) == 3) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
}
|
||||||
if((i & 15) == 15)
|
if((i & 15) == 15)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -279,7 +292,6 @@ write_to_serial(int outfd, void *inbuf, int len)
|
||||||
slip_send(outfd, p[i]);
|
slip_send(outfd, p[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
slip_send(outfd, SLIP_END);
|
slip_send(outfd, SLIP_END);
|
||||||
PROGRESS("t");
|
PROGRESS("t");
|
||||||
|
@ -354,7 +366,7 @@ devopen(const char *dev, int flags)
|
||||||
{
|
{
|
||||||
char t[32];
|
char t[32];
|
||||||
strcpy(t, "/dev/");
|
strcpy(t, "/dev/");
|
||||||
strcat(t, dev);
|
strncat(t, dev, sizeof(t) - 5);
|
||||||
return open(t, flags);
|
return open(t, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,8 +380,9 @@ tun_alloc(char *dev, int tap)
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int fd, err;
|
int fd, err;
|
||||||
|
|
||||||
if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
|
if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
|
||||||
|
@ -382,7 +395,7 @@ tun_alloc(char *dev, int tap)
|
||||||
if(*dev != 0)
|
if(*dev != 0)
|
||||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||||
|
|
||||||
if((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
|
if((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -465,13 +478,18 @@ main(int argc, char **argv)
|
||||||
fd_set rset, wset;
|
fd_set rset, wset;
|
||||||
FILE *inslip;
|
FILE *inslip;
|
||||||
const char *siodev = NULL;
|
const char *siodev = NULL;
|
||||||
|
const char *host = NULL;
|
||||||
|
const char *port = NULL;
|
||||||
|
const char *prog;
|
||||||
int baudrate = -2;
|
int baudrate = -2;
|
||||||
int tap = 0;
|
int tap = 0;
|
||||||
|
slipfd = 0;
|
||||||
|
|
||||||
|
prog = argv[0];
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */
|
setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */
|
||||||
|
|
||||||
while((c = getopt(argc, argv, "B:D:hs:t:v:T")) != -1) {
|
while((c = getopt(argc, argv, "B:D:hs:t:v:a:p:T")) != -1) {
|
||||||
switch (c) {
|
switch(c) {
|
||||||
case 'B':
|
case 'B':
|
||||||
baudrate = atoi(optarg);
|
baudrate = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -486,22 +504,30 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
if(strncmp("/dev/", optarg, 5) == 0) {
|
if(strncmp("/dev/", optarg, 5) == 0) {
|
||||||
strcpy(tundev, optarg + 5);
|
strncpy(tundev, optarg + 5, sizeof(tundev));
|
||||||
} else {
|
} else {
|
||||||
strcpy(tundev, optarg);
|
strncpy(tundev, optarg, sizeof(tundev));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
host = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
port = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
printf("TAP");
|
|
||||||
tap = 1;
|
tap = 1;
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
err(1, "usage: tunslip6 [-B baudrate] [-s siodev] [-t tundev] [-T] ipaddress");
|
err(1, "usage: %s [-B baudrate] [-s siodev] [-t tundev] [-T] [-a serveraddress] [-p serverport] ipaddress", prog);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -509,7 +535,7 @@ main(int argc, char **argv)
|
||||||
argv += (optind - 1);
|
argv += (optind - 1);
|
||||||
|
|
||||||
if(argc != 2 && argc != 3) {
|
if(argc != 2 && argc != 3) {
|
||||||
err(1, "usage: tunslip6 [-B baudrate] [-s siodev] [-t tundev] [-T] ipaddress ");
|
err(1, "usage: %s [-B baudrate] [-s siodev] [-t tundev] [-T] [-a serveraddress] [-p serverport] ipaddress", prog);
|
||||||
}
|
}
|
||||||
ipaddr = argv[1];
|
ipaddr = argv[1];
|
||||||
|
|
||||||
|
@ -536,7 +562,61 @@ main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
if(siodev != NULL) {
|
||||||
slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
|
slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
|
||||||
if(slipfd == -1) {
|
if(slipfd == -1) {
|
||||||
|
@ -550,22 +630,25 @@ main(int argc, char **argv)
|
||||||
for(i = 0; i < 3; i++) {
|
for(i = 0; i < 3; i++) {
|
||||||
siodev = siodevs[i];
|
siodev = siodevs[i];
|
||||||
slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
|
slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
|
||||||
if (slipfd != -1)
|
if(slipfd != -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(slipfd == -1) {
|
if(slipfd == -1) {
|
||||||
err(1, "can't open siodev");
|
err(1, "can't open siodev");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr, "slip started on ``/dev/%s''\n", siodev);
|
fprintf(stderr, "slip started on ``/dev/%s''\n", siodev);
|
||||||
stty_telos(slipfd);
|
stty_telos(slipfd);
|
||||||
|
}
|
||||||
slip_send(slipfd, SLIP_END);
|
slip_send(slipfd, SLIP_END);
|
||||||
inslip = fdopen(slipfd, "r");
|
inslip = fdopen(slipfd, "r");
|
||||||
if(inslip == NULL) err(1, "main: fdopen");
|
if(inslip == NULL) err(1, "main: fdopen");
|
||||||
|
|
||||||
tunfd = tun_alloc(tundev, tap);
|
tunfd = tun_alloc(tundev, tap);
|
||||||
if(tunfd == -1) err(1, "main: open");
|
if(tunfd == -1) err(1, "main: open");
|
||||||
fprintf(stderr, "opened device ``/dev/%s''\n", tundev);
|
fprintf(stderr, "opened %s device ``/dev/%s''\n",
|
||||||
|
tap ? "tap" : "tun", tundev);
|
||||||
|
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
signal(SIGHUP, sigcleanup);
|
signal(SIGHUP, sigcleanup);
|
||||||
|
|
Loading…
Reference in a new issue