Fancier tunslip with keepalives, address detection, route management,
route cleanup.
This commit is contained in:
parent
17431ba16c
commit
1429faa22e
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the uIP TCP/IP stack.
|
* This file is part of the uIP TCP/IP stack.
|
||||||
*
|
*
|
||||||
* $Id: tunslip.c,v 1.3 2006/09/07 17:05:21 bg- Exp $
|
* $Id: tunslip.c,v 1.4 2006/09/26 15:45:09 bg- Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -153,6 +153,8 @@ in_addr_t giaddr;
|
||||||
in_addr_t netaddr;
|
in_addr_t netaddr;
|
||||||
in_addr_t circuit_addr;
|
in_addr_t circuit_addr;
|
||||||
|
|
||||||
|
char tundev[32] = { "tun0" };
|
||||||
|
|
||||||
struct sockaddr_in dhaddr;
|
struct sockaddr_in dhaddr;
|
||||||
int dhsock = -1;
|
int dhsock = -1;
|
||||||
|
|
||||||
|
@ -479,7 +481,23 @@ serial_to_tun(FILE *inslip, int outfd)
|
||||||
#define DEBUG_LINE_MARKER '\r'
|
#define DEBUG_LINE_MARKER '\r'
|
||||||
int ecode;
|
int ecode;
|
||||||
ecode = check_ip(&uip.iphdr, inbufptr);
|
ecode = check_ip(&uip.iphdr, inbufptr);
|
||||||
if(ecode < 0) {
|
if(ecode < 0 && inbufptr == 8 && strncmp(uip.inbuf, "=IPA", 4) == 0) {
|
||||||
|
static struct in_addr ipa;
|
||||||
|
|
||||||
|
inbufptr = 0;
|
||||||
|
if(memcmp(&ipa, &uip.inbuf[4], sizeof(ipa)) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
memcpy(&ipa, &uip.inbuf[4], sizeof(ipa));
|
||||||
|
#ifdef linux
|
||||||
|
ssystem("route add -net %s netmask %s dev %s",
|
||||||
|
inet_ntoa(ipa), "255.255.255.255", tundev);
|
||||||
|
#else
|
||||||
|
ssystem("route add -net %s -netmask %s -interface %s",
|
||||||
|
inet_ntoa(ipa), "255.255.255.255", tundev);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
} else if(ecode < 0) {
|
||||||
/*
|
/*
|
||||||
* If sensible ASCII string, print it as debug info!
|
* If sensible ASCII string, print it as debug info!
|
||||||
*/
|
*/
|
||||||
|
@ -737,38 +755,46 @@ tun_alloc(char *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char tundev[32] = { "tun0" };
|
|
||||||
const char *ipaddr;
|
const char *ipaddr;
|
||||||
const char *netmask;
|
const char *netmask;
|
||||||
|
|
||||||
void
|
void
|
||||||
cleanup(int signo)
|
cleanup(void)
|
||||||
|
{
|
||||||
|
ssystem("ifconfig %s down", tundev);
|
||||||
|
#ifndef linux
|
||||||
|
ssystem("sysctl net.inet.ip.forwarding=0");
|
||||||
|
#endif
|
||||||
|
/* ssystem("arp -d %s", ipaddr); */
|
||||||
|
ssystem("netstat -nr"
|
||||||
|
" | awk '{ if ($2 == \"%s\") print \"route delete -net \"$1; }'"
|
||||||
|
" | sh",
|
||||||
|
tundev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sigcleanup(int signo)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "signal %d\n", signo);
|
fprintf(stderr, "signal %d\n", signo);
|
||||||
#ifdef linux
|
exit(0); /* exit(0) will call cleanup() */
|
||||||
#else
|
|
||||||
ssystem("sysctl net.inet.ip.forwarding=0");
|
|
||||||
/* ssystem("arp -d %s", ipaddr); */
|
|
||||||
ssystem("ifconfig %s delete", tundev);
|
|
||||||
#endif
|
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ifconf(const char *tundev, const char *ipaddr, const char *netmask)
|
ifconf(const char *tundev, const char *ipaddr, const char *netmask)
|
||||||
{
|
{
|
||||||
#ifdef linux
|
|
||||||
struct in_addr netname;
|
struct in_addr netname;
|
||||||
netname.s_addr = inet_addr(ipaddr) & inet_addr(netmask);
|
netname.s_addr = inet_addr(ipaddr) & inet_addr(netmask);
|
||||||
|
|
||||||
|
#ifdef linux
|
||||||
ssystem("ifconfig %s inet `hostname` up", tundev);
|
ssystem("ifconfig %s inet `hostname` up", tundev);
|
||||||
|
if (strcmp(ipaddr, "0.0.0.0") != 0)
|
||||||
ssystem("route add -net %s netmask %s dev %s",
|
ssystem("route add -net %s netmask %s dev %s",
|
||||||
inet_ntoa(netname), netmask, tundev);
|
inet_ntoa(netname), netmask, tundev);
|
||||||
#else
|
#else
|
||||||
ssystem("ifconfig %s inet `hostname` %s netmask %s up",
|
ssystem("ifconfig %s inet up", tundev);
|
||||||
tundev, ipaddr, netmask);
|
if (strcmp(ipaddr, "0.0.0.0") != 0)
|
||||||
ssystem("route add -net %s -netmask %s -interface %s",
|
ssystem("route add -net %s -netmask %s -interface %s",
|
||||||
ipaddr, netmask, tundev);
|
inet_ntoa(netname), netmask, tundev);
|
||||||
/* ssystem("arp -s %s auto pub only", ipaddr); */
|
|
||||||
ssystem("sysctl net.inet.ip.forwarding=1");
|
ssystem("sysctl net.inet.ip.forwarding=1");
|
||||||
#endif /* !linux */
|
#endif /* !linux */
|
||||||
|
|
||||||
|
@ -782,6 +808,8 @@ main(int argc, char **argv)
|
||||||
int tunfd, slipfd, maxfd;
|
int tunfd, slipfd, maxfd;
|
||||||
int ret;
|
int ret;
|
||||||
fd_set rset, wset;
|
fd_set rset, wset;
|
||||||
|
struct timeval timeout;
|
||||||
|
const char helo[6] = { SLIP_END, '?', 'I', 'P', 'A', SLIP_END };
|
||||||
FILE *inslip;
|
FILE *inslip;
|
||||||
const char *siodev = NULL;
|
const char *siodev = NULL;
|
||||||
const char *dhcp_server = NULL;
|
const char *dhcp_server = NULL;
|
||||||
|
@ -812,7 +840,7 @@ main(int argc, char **argv)
|
||||||
case '?':
|
case '?':
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
err(1, "usage: tunslip [-s siodev] [-t tundev] [-d dhcp-server] ipaddress netmask [dhcp-server]");
|
err(1, "usage: tunslip [-s siodev] [-t tundev] [-D dhcp-server] ipaddress netmask [dhcp-server]");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -820,7 +848,7 @@ main(int argc, char **argv)
|
||||||
argv += (optind - 1);
|
argv += (optind - 1);
|
||||||
|
|
||||||
if (argc != 3 && argc != 4)
|
if (argc != 3 && argc != 4)
|
||||||
err(1, "usage: tunslip ipaddress netmask [dhcp-server]");
|
err(1, "usage: tunslip [-s siodev] [-t tundev] [-D dhcp-server] ipaddress netmask [dhcp-server]");
|
||||||
ipaddr = argv[1];
|
ipaddr = argv[1];
|
||||||
netmask = argv[2];
|
netmask = argv[2];
|
||||||
circuit_addr = inet_addr(ipaddr);
|
circuit_addr = inet_addr(ipaddr);
|
||||||
|
@ -916,9 +944,10 @@ main(int argc, char **argv)
|
||||||
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 device ``/dev/%s''\n", tundev);
|
||||||
|
|
||||||
signal(SIGHUP, cleanup);
|
atexit(cleanup);
|
||||||
signal(SIGTERM, cleanup);
|
signal(SIGHUP, sigcleanup);
|
||||||
signal(SIGINT, cleanup);
|
signal(SIGTERM, sigcleanup);
|
||||||
|
signal(SIGINT, sigcleanup);
|
||||||
ifconf(tundev, ipaddr, netmask);
|
ifconf(tundev, ipaddr, netmask);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
@ -942,10 +971,16 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = select(maxfd + 1, &rset, &wset, NULL, NULL);
|
timeout.tv_sec = 1;
|
||||||
|
timeout.tv_usec = 450*1000;
|
||||||
|
ret = select(maxfd + 1, &rset, &wset, NULL, &timeout);
|
||||||
if(ret == -1)
|
if(ret == -1)
|
||||||
err(1, "select");
|
err(1, "select");
|
||||||
else if(ret > 0) {
|
else if(ret == 0 && slip_empty()) {
|
||||||
|
ret = write(slipfd, helo, sizeof(helo));
|
||||||
|
if(ret != sizeof(helo))
|
||||||
|
err(1, "write helo");
|
||||||
|
} else if(ret > 0) {
|
||||||
if(FD_ISSET(slipfd, &rset))
|
if(FD_ISSET(slipfd, &rset))
|
||||||
serial_to_tun(inslip, tunfd);
|
serial_to_tun(inslip, tunfd);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue