Added option to connect to server instead of serial port

This commit is contained in:
nifi 2010-05-07 12:22:41 +00:00
parent 4aba60ad25
commit 99b2dd8ef7

View File

@ -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,9 +234,10 @@ 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));
if(n == -1 && errno != EAGAIN) { if(n == -1 && errno != EAGAIN) {
@ -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,36 +562,93 @@ 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(siodev != NULL) { 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); slipfd = devopen(siodev, O_RDWR | O_NONBLOCK);
if(slipfd == -1) { if(slipfd == -1) {
err(1, "can't open siodev ``/dev/%s''", siodev); err(1, "can't open siodev ``/dev/%s''", siodev);
} }
} else { } else {
static const char *siodevs[] = { static const char *siodevs[] = {
"ttyUSB0", "cuaU0", "ucom0" /* linux, fbsd6, fbsd5 */ "ttyUSB0", "cuaU0", "ucom0" /* linux, fbsd6, fbsd5 */
}; };
int i; int i;
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) { }
err(1, "can't open siodev"); if(slipfd == -1) {
err(1, "can't open siodev");
}
} }
fprintf(stderr, "slip started on ``/dev/%s''\n", siodev);
stty_telos(slipfd);
} }
fprintf(stderr, "slip started on ``/dev/%s''\n", siodev);
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);