755 lines
16 KiB
C
755 lines
16 KiB
C
#ifdef linux
|
|
#define ARP_PATH "/sbin/arp"
|
|
#define INET_BSD
|
|
#include <linux/config.h>
|
|
#ifdef CONFIG_INET_BSD
|
|
#define SOCK_HAS_LEN
|
|
#else
|
|
#define SET_STEP
|
|
#define ROUTE_IF
|
|
#endif
|
|
#include <linux/sockios.h>
|
|
#endif
|
|
#include "primitives.h"
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/file.h>
|
|
#include "f_ioctl.h"
|
|
#include "f_ip.h"
|
|
#include <sys/sysmacros.h>
|
|
#include "stropts.h"
|
|
#include "f_termio.h"
|
|
#include <sys/signal.h>
|
|
#include <sys/socket.h>
|
|
#include <errno.h>
|
|
#include <net/if.h>
|
|
#ifdef CONFIG_INET_BSD
|
|
#include <net/if_slvar.h>
|
|
#include <net/slip.h>
|
|
#else
|
|
#include <linux/if_slip.h>
|
|
#endif
|
|
#include <arpa/inet.h>
|
|
#ifdef SYSV
|
|
#include <sys/stream.h>
|
|
#endif
|
|
#include <netinet/in.h>
|
|
#include <netdb.h>
|
|
#include <syslog.h>
|
|
#ifdef AUX
|
|
#include <compat.h>
|
|
#endif
|
|
#include <fcntl.h>
|
|
#include <strings.h>
|
|
|
|
#include "str_if.h"
|
|
#include "sioctl.h"
|
|
|
|
void
|
|
xquit (const char *s)
|
|
{
|
|
syslog (LOG_WARNING, "%s: %m", s ? s : "(NULL)");
|
|
exit (3);
|
|
}
|
|
|
|
void
|
|
squit (int sig)
|
|
{
|
|
syslog (LOG_INFO, "Sig %d", sig);
|
|
xquit (NULL);
|
|
}
|
|
|
|
void
|
|
quit (void)
|
|
{
|
|
xquit ("Trouble");
|
|
}
|
|
|
|
struct hostent *
|
|
host_name (const char *name)
|
|
{
|
|
struct hostent *h = gethostbyname (name);
|
|
|
|
if (h == NULL) {
|
|
static struct hostent def;
|
|
static struct in_addr defaddr;
|
|
static char *alist[1];
|
|
static char namebuf[128];
|
|
|
|
defaddr.s_addr = inet_addr (name);
|
|
if (defaddr.s_addr == -1)
|
|
return NULL;
|
|
strcpy (namebuf, name);
|
|
def.h_name = namebuf;
|
|
def.h_addr_list = alist, def.h_addr = (char *) &defaddr;
|
|
def.h_length = sizeof (struct in_addr);
|
|
|
|
def.h_addrtype = AF_INET;
|
|
def.h_aliases = 0;
|
|
h = &def;
|
|
}
|
|
return h;
|
|
}
|
|
|
|
static char ifname[IFNAMSIZ];
|
|
static int s;
|
|
int devfd = 0;
|
|
int dontroutemyhost=0;
|
|
char *dev = NULL;
|
|
|
|
char makeroute[2000], unmakeroute[2000];
|
|
|
|
ushort_t id = 0;
|
|
long ich = 0, du = 0, mask = 0;
|
|
char *ichaddr, *duaddr, *arpaddr = NULL;
|
|
int islinked = 0;
|
|
int ifflags = IFF_UP|IFF_POINTOPOINT;
|
|
int mtu = 0;
|
|
|
|
char *destaddr[20];
|
|
char **destxaddr = destaddr;
|
|
|
|
char *desthaddr[20];
|
|
char **desthxaddr = desthaddr;
|
|
|
|
void
|
|
enable (void)
|
|
{
|
|
int xid;
|
|
|
|
if (islinked)
|
|
return;
|
|
|
|
#ifdef SIOCGIFNAME
|
|
if(ioctl(devfd,SIOCGIFNAME,&ifname) >= 0)
|
|
xid = atoi(strpbrk(ifname,"0123456789"));
|
|
else
|
|
#endif
|
|
#ifdef SIOCGETU
|
|
if (sioctl (devfd, SIOCGETU, &xid) >= 0)
|
|
sprintf (ifname, "str%d", xid);
|
|
else
|
|
#endif
|
|
#ifdef SLIOCGUNIT
|
|
if(ioctl(devfd,SLIOCGUNIT,&xid) >= 0)
|
|
sprintf (ifname, "str%d", xid);
|
|
else
|
|
#endif
|
|
xquit ("GetU");
|
|
id = xid;
|
|
|
|
syslog(LOG_DEBUG,"Setting up IF %s",ifname);
|
|
if(makeroute[0]=='\0') {
|
|
struct hostent *h;
|
|
char **y;
|
|
|
|
if ((h = host_name (ichaddr)) == NULL)
|
|
xquit (ichaddr);
|
|
ich = *(long *) h->h_addr;
|
|
if ((h = host_name (duaddr)) == NULL)
|
|
xquit (duaddr);
|
|
du = *(long *) h->h_addr;
|
|
|
|
makeroute[0]='\0';
|
|
#if 0
|
|
sprintf(makeroute+strlen(makeroute),"set -xv; exec >>/tmp/sll 2>&1 </dev/null; ");
|
|
sprintf(unmakeroute+strlen(unmakeroute),"set -xv; exec >>/tmp/sll 2>&1 </dev/null; ");
|
|
#endif
|
|
|
|
#ifdef ROUTE_IF
|
|
if(!dontroutemyhost)
|
|
sprintf(makeroute+strlen(makeroute), "%s add -host %s metric 2 dev %s; ", ROUTE_PATH,ichaddr,ifname);
|
|
sprintf(makeroute+strlen(makeroute), "%s add -host %s metric 2 " /* "gw %s" */ " dev %s; ", ROUTE_PATH,duaddr, /* ichaddr, */ ifname);
|
|
if(arpaddr != NULL)
|
|
sprintf(makeroute+strlen(makeroute), "%s -s %s %s pub; ", ARP_PATH,duaddr,arpaddr);
|
|
|
|
sprintf(unmakeroute+strlen(unmakeroute), "%s del -host %s gw %s dev %s; ",ROUTE_PATH,duaddr,ichaddr,ifname);
|
|
if(arpaddr != NULL)
|
|
sprintf(unmakeroute+strlen(unmakeroute), "%s -d %s; ",ARP_PATH,duaddr);
|
|
#endif
|
|
|
|
for(y = destaddr;y != destxaddr;y++) {
|
|
char *foo; char xbuf[50];
|
|
char *route;
|
|
|
|
route = strchr(*y,':');
|
|
if(route == NULL)
|
|
route = strchr(*y,'/');
|
|
if(route) {
|
|
char rc = *route;
|
|
if(*route == '/') {
|
|
static char s[20];
|
|
unsigned long mask;
|
|
|
|
*route++ = '\0';
|
|
mask = (~0)<<(32-atoi(route));
|
|
foo = s;
|
|
sprintf(s,"%ld.%ld.%ld.%ld",(mask>>24)&0xFF,(mask>>16)&0xFF,(mask>>8)&0xFF,mask&0xFF);
|
|
} else {
|
|
*route++ = '\0';
|
|
foo = route;
|
|
}
|
|
#ifdef SET_STEP
|
|
sprintf(xbuf, "%s netmask %s",*y,foo);
|
|
#else
|
|
sprintf(xbuf, "%s -netmask %s",*y,foo);
|
|
#endif
|
|
*--route = rc;
|
|
foo = xbuf;
|
|
} else {
|
|
foo = *y;
|
|
}
|
|
#ifdef SET_STEP
|
|
sprintf (makeroute+strlen(makeroute), "%s add -net %s gw %s metric 2 dev %s; ", ROUTE_PATH, foo,duaddr,ifname);
|
|
sprintf (unmakeroute+strlen(unmakeroute), "%s del -net %s dev %s; ", ROUTE_PATH, foo,ifname);
|
|
#else
|
|
sprintf (makeroute+strlen(makeroute), "%s -- add %s %s; ", ROUTE_PATH, foo,duaddr);
|
|
sprintf (unmakeroute+strlen(unmakeroute), "%s -- delete %s %s; ", ROUTE_PATH, foo,duaddr);
|
|
#endif
|
|
}
|
|
for(y = desthaddr;y != desthxaddr;y++) {
|
|
#ifdef SET_STEP
|
|
sprintf (makeroute+strlen(makeroute), "%s add -host %s gw %s metric 2 dev %s; ", ROUTE_PATH, *y,duaddr,ifname);
|
|
if(arpaddr != NULL)
|
|
sprintf(makeroute+strlen(makeroute), "%s -s %s %s pub; ", ARP_PATH, *y, arpaddr);
|
|
|
|
sprintf (unmakeroute+strlen(unmakeroute), "%s del -host %s dev %s; ", ROUTE_PATH, *y, ifname);
|
|
if(arpaddr != NULL)
|
|
sprintf(unmakeroute+strlen(unmakeroute), "%s -d %s; ",ARP_PATH, *y);
|
|
#else
|
|
sprintf (makeroute+strlen(makeroute), "%s -- add %s %s; ", ROUTE_PATH, *y,duaddr);
|
|
sprintf (unmakeroute+strlen(unmakeroute), "%s -- delete %s %s; ", ROUTE_PATH, *y,duaddr);
|
|
#endif
|
|
}
|
|
}
|
|
#ifndef SET_STEP
|
|
{
|
|
struct ifreq ifr;
|
|
|
|
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
|
if (ioctl (s, SIOCGIFFLAGS, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
|
quit ();
|
|
}
|
|
ifr.ifr_flags |= ifflags;
|
|
if (ioctl (s, SIOCSIFFLAGS, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
|
quit ();
|
|
}
|
|
if(mtu > 0) {
|
|
ifr.ifr_mtu = mtu;
|
|
if (ioctl (s, SIOCSIFMTU, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCSIFMTU): %m");
|
|
quit ();
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
{
|
|
struct ifreq ifr;
|
|
|
|
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
|
ifr.ifr_addr.sa_family = AF_INET;
|
|
#ifdef SOCK_HAS_LEN
|
|
ifr.ifr_addr.sa_len = sizeof(struct sockaddr_in);
|
|
#endif
|
|
if (ioctl (s, SIOCGIFADDR, (caddr_t) & ifr) < 0) {
|
|
if(errno != EADDRNOTAVAIL) {
|
|
syslog (LOG_ERR, "ioctl (SIOCGIFADDR): %m");
|
|
quit ();
|
|
}
|
|
} else {
|
|
#ifndef SET_STEP
|
|
if (ioctl (s, SIOCDIFADDR, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCDIFADDR): %m");
|
|
quit ();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
}
|
|
#ifdef SET_STEP
|
|
{
|
|
struct ifreq ifr;
|
|
|
|
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
|
ifr.ifr_addr.sa_family = AF_INET;
|
|
#ifdef SOCK_HAS_LEN
|
|
ifr.ifr_addr.sa_len = sizeof(struct sockaddr_in);
|
|
#endif
|
|
((struct sockaddr_in *) & ifr.ifr_dstaddr)->sin_addr.s_addr = ich;
|
|
if (ioctl(s, SIOCSIFADDR, &ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCSIFADDR %d.%d.%d.%d %d.%d.%d.%d): %m",
|
|
((uchar_t *)&ich)[0], ((uchar_t *)&ich)[1], ((uchar_t *)&ich)[2], ((uchar_t *)&ich)[3],
|
|
((uchar_t *)&du )[0], ((uchar_t *)&du )[1], ((uchar_t *)&du )[2], ((uchar_t *)&du )[3]);
|
|
quit();
|
|
}
|
|
|
|
ifr.ifr_addr.sa_family = AF_INET;
|
|
#ifdef SOCK_HAS_LEN
|
|
ifr.ifr_addr.sa_len = sizeof(struct sockaddr_in);
|
|
#endif
|
|
((struct sockaddr_in *) & ifr.ifr_dstaddr)->sin_addr.s_addr = du;
|
|
if (ioctl(s, SIOCSIFDSTADDR, &ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCSIFDSTADDR %d.%d.%d.%d %d.%d.%d.%d): %m",
|
|
((uchar_t *)&ich)[0], ((uchar_t *)&ich)[1], ((uchar_t *)&ich)[2], ((uchar_t *)&ich)[3],
|
|
((uchar_t *)&du )[0], ((uchar_t *)&du )[1], ((uchar_t *)&du )[2], ((uchar_t *)&du )[3]);
|
|
quit();
|
|
}
|
|
|
|
if (mask != 0) {
|
|
ifr.ifr_addr.sa_family = AF_INET;
|
|
#ifdef SOCK_HAS_LEN
|
|
ifr.ifr_addr.sa_len = sizeof(struct sockaddr_in);
|
|
#endif
|
|
((struct sockaddr_in *) & ifr.ifr_netmask)->sin_addr.s_addr = mask;
|
|
if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCSIFNETMASK): %m");
|
|
quit();
|
|
}
|
|
}
|
|
}
|
|
{
|
|
struct ifreq ifr;
|
|
|
|
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
|
if (ioctl (s, SIOCGIFFLAGS, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
|
quit ();
|
|
}
|
|
ifr.ifr_flags |= ifflags;
|
|
if (ioctl (s, SIOCSIFFLAGS, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
|
quit ();
|
|
}
|
|
if(mtu > 0) {
|
|
ifr.ifr_mtu = mtu;
|
|
if (ioctl (s, SIOCSIFMTU, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCSIFMTU): %m");
|
|
quit ();
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
{
|
|
struct ifaliasreq ifr;
|
|
|
|
bzero ((char *) &ifr, sizeof (ifr));
|
|
strncpy (ifr.ifra_name, ifname, sizeof (ifr.ifra_name));
|
|
|
|
ifr.ifra_addr.sa_family = AF_INET;
|
|
#ifdef SOCK_HAS_LEN
|
|
ifr.ifra_addr.sa_len = sizeof(struct sockaddr_in);
|
|
#endif
|
|
((struct sockaddr_in *) & ifr.ifra_addr)->sin_addr.s_addr = ich;
|
|
|
|
ifr.ifra_dstaddr.sa_family = AF_INET;
|
|
#ifdef SOCK_HAS_LEN
|
|
ifr.ifra_dstaddr.sa_len = sizeof(struct sockaddr_in);
|
|
#endif
|
|
((struct sockaddr_in *) & ifr.ifra_dstaddr)->sin_addr.s_addr = du;
|
|
|
|
if (mask != 0) {
|
|
|
|
/* ifr.ifra_mask.sa_family = AF_INET; */
|
|
#ifdef SOCK_HAS_LEN
|
|
ifr.ifra_mask.sa_len = sizeof(struct sockaddr_in);
|
|
#endif
|
|
((struct sockaddr_in *) & ifr.ifra_mask)->sin_addr.s_addr = mask;
|
|
|
|
if (ioctl (s, SIOCAIFADDR, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCAIFADDR %d.%d.%d.%d %d.%d.%d.%d): %m",
|
|
((uchar_t *)&ich)[0], ((uchar_t *)&ich)[1], ((uchar_t *)&ich)[2], ((uchar_t *)&ich)[3],
|
|
((uchar_t *)&du )[0], ((uchar_t *)&du )[1], ((uchar_t *)&du)[2], ((uchar_t *)&du )[3]);
|
|
xquit ("Dead");
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
islinked = 1;
|
|
if(fork() == 0) {
|
|
signal(SIGCHLD,SIG_DFL);
|
|
fprintf(stderr,"<<%s>>\n",makeroute);
|
|
execl("/bin/sh","sh","-c",makeroute,NULL);
|
|
/* system (makeroute); */
|
|
}
|
|
}
|
|
|
|
void
|
|
disable (void)
|
|
{
|
|
if (!islinked)
|
|
return;
|
|
|
|
syslog(LOG_DEBUG,"Taking down IF %s",ifname);
|
|
if(fork() == 0) {
|
|
signal(SIGCHLD,SIG_DFL);
|
|
fprintf(stderr,"<<%s>>\n",unmakeroute);
|
|
execl("/bin/sh","sh","-c",unmakeroute,NULL);
|
|
}
|
|
{
|
|
struct ifreq ifr;
|
|
|
|
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
|
if (ioctl (s, SIOCGIFFLAGS, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl (SIOCGIFFLAGS): %m");
|
|
quit ();
|
|
}
|
|
ifr.ifr_flags &= ~IFF_UP;
|
|
if (ioctl (s, SIOCSIFFLAGS, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
|
|
quit ();
|
|
}
|
|
|
|
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
|
|
ifr.ifr_addr.sa_family = AF_INET;
|
|
#ifdef SOCK_HAS_LEN
|
|
ifr.ifr_addr.sa_len = sizeof(struct sockaddr_in);
|
|
#endif
|
|
if (ioctl (s, SIOCGIFADDR, (caddr_t) & ifr) < 0) {
|
|
if(errno != EADDRNOTAVAIL)
|
|
syslog (LOG_ERR, "ioctl (SIOCGIFADDR): %m");
|
|
} else {
|
|
#ifndef SET_STEP
|
|
if (ioctl (s, SIOCDIFADDR, (caddr_t) & ifr) < 0) {
|
|
syslog (LOG_ERR, "ioctl(SIOCDIFADDR): %m");
|
|
quit ();
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
islinked = 0;
|
|
}
|
|
|
|
void
|
|
disableq (void)
|
|
{
|
|
disable ();
|
|
syslog(LOG_INFO,"Exit DisableQ");
|
|
exit (0);
|
|
}
|
|
|
|
void
|
|
sigon (void)
|
|
{
|
|
syslog (LOG_INFO, "Sig USR1");
|
|
enable ();
|
|
}
|
|
|
|
void
|
|
sigoff (void)
|
|
{
|
|
syslog (LOG_INFO, "Sig USR2");
|
|
disable ();
|
|
}
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
extern char *optarg;
|
|
extern int optind;
|
|
char *progname = *argv;
|
|
int pid = getpid ();
|
|
int dodial = 0, domon = 0, dovanj = 0, dofakeh = 0, dolog = 0, dologmodem = 0,
|
|
docount = 0, doqinfo = 0, noslip = 0, doenable = 0, dodebug = 0;
|
|
int speed = 0;
|
|
|
|
#ifdef AUX
|
|
setcompat (COMPAT_BSD);
|
|
#endif
|
|
alarm(0);
|
|
|
|
openlog (progname, LOG_PID|LOG_PERROR, LOG_LOCAL7);
|
|
|
|
signal (SIGUSR1, (sigfunc__t) enable);
|
|
signal (SIGUSR2, (sigfunc__t) disable);
|
|
signal (SIGPWR, (sigfunc__t) disable);
|
|
signal (SIGHUP, (sigfunc__t) disableq);
|
|
signal (SIGINT, (sigfunc__t) disableq);
|
|
signal (SIGTERM, (sigfunc__t) disableq);
|
|
signal (SIGQUIT, (sigfunc__t) disableq);
|
|
signal (SIGCHLD, SIG_IGN);
|
|
signal (SIGTTOU, SIG_IGN);
|
|
|
|
while ((s = getopt (argc, argv, "Ddr:R:lEMm:vfLop:s:S:A:x")) != EOF)
|
|
switch (s) {
|
|
case 'x':
|
|
dontroutemyhost=1;
|
|
break;
|
|
case 'D':
|
|
dodebug = 1;
|
|
break;
|
|
case 'S':
|
|
noslip = 1;
|
|
break;
|
|
case 's':
|
|
speed = atoi(optarg);
|
|
break;
|
|
case 'l':
|
|
dolog ++;
|
|
break;
|
|
case 'L':
|
|
dologmodem = 1;
|
|
break;
|
|
case 'E':
|
|
doenable = 1;
|
|
break;
|
|
case 'm':
|
|
mtu = atoi(optarg);
|
|
break;
|
|
case 'M':
|
|
domon = 1;
|
|
break;
|
|
case 'f':
|
|
dofakeh = 1;
|
|
break;
|
|
case 'v':
|
|
dovanj = 1;
|
|
break;
|
|
case 'o':
|
|
dodial = 1;
|
|
break;
|
|
case 'p':
|
|
dev = optarg;
|
|
break;
|
|
case 'd':
|
|
*destxaddr++ = "default";
|
|
break;
|
|
case 'R':
|
|
*desthxaddr++ = optarg;
|
|
break;
|
|
case 'r':
|
|
*destxaddr++ = optarg;
|
|
break;
|
|
case 'A': /* Proxy ARP */
|
|
arpaddr = optarg;
|
|
break;
|
|
case '?':
|
|
default:
|
|
usage:
|
|
fprintf (stderr, "Usage: %s [-d {-r route}... -p device -o -l -m -v -A xx:xx:xx:xx:xx:xx ] from to\n", progname);
|
|
syslog(LOG_ERR,"Usage!");
|
|
exit (99);
|
|
}
|
|
|
|
argv += optind;
|
|
argc -= optind;
|
|
if (argc != 2)
|
|
goto usage;
|
|
|
|
ichaddr = *argv++;
|
|
duaddr = *argv++;
|
|
|
|
if(!dodebug)
|
|
freopen("/dev/null","w",stderr);
|
|
|
|
if ((s = socket (AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0)
|
|
xquit ("socket");
|
|
|
|
if (dev != NULL) {
|
|
if (dodial)
|
|
if ((devfd = open ("/dev/tty", O_RDWR)) >= 0) {
|
|
#ifdef TIOCNOTTY
|
|
(void) ioctl (devfd, TIOCNOTTY, 0);
|
|
#endif
|
|
close (devfd);
|
|
}
|
|
if ((devfd = open (dev, O_RDWR)) < 0) {
|
|
syslog (LOG_ERR,"%s: %m",dev);
|
|
exit (1);
|
|
} {
|
|
struct termios ts;
|
|
|
|
#ifdef UIOCFLOW
|
|
ioctl(devfd,UIOCFLOW,0);
|
|
#endif
|
|
#ifdef UIOCMODEM
|
|
ioctl(devfd,UIOCMODEM,0);
|
|
#endif
|
|
if (ioctl (devfd, TCGETS, &ts) == 0) {
|
|
int i;
|
|
long ocflag = ts.c_cflag;
|
|
for(i = 0; i < NCCS; i++)
|
|
ts.c_cc[i] = '\0';
|
|
ts.c_cc[VMIN] = 1;
|
|
ts.c_cc[VTIME] = 0;
|
|
ts.c_iflag = (BRKINT);
|
|
ts.c_oflag = (0);
|
|
ts.c_lflag = (0);
|
|
ts.c_cflag = (CRTSCTS|HUPCL|CREAD|CS8);
|
|
if(speed == 0)
|
|
ts.c_cflag |= ocflag&CBAUD;
|
|
else {
|
|
cfsetispeed(&ts,speed);
|
|
cfsetospeed(&ts,speed);
|
|
}
|
|
if (ioctl (devfd, TCSETSF, &ts) != 0) {
|
|
syslog (LOG_ERR,"%s TCSETSF: %m",dev);
|
|
exit (1);
|
|
}
|
|
}
|
|
}
|
|
if (dodial) {
|
|
ioctl (devfd, I_PUSH, "strlog");
|
|
write (devfd, "AT&L1A\r", 7);
|
|
sleep (1);
|
|
ioctl (devfd, TCFLSH, 0);
|
|
ioctl (devfd, I_FLUSH, FLUSHR);
|
|
dor:
|
|
{
|
|
char c;
|
|
|
|
if (read (devfd, &c, 1) != 1)
|
|
syslog (LOG_ERR,"read: %m");
|
|
if (c == '\r' || c == '\n')
|
|
goto dor;
|
|
if (c != 'C') {
|
|
syslog (LOG_ERR,"got %02x: %m",c);
|
|
exit (1);
|
|
}
|
|
}
|
|
sleep (1);
|
|
ioctl (devfd, TCFLSH, 0);
|
|
ioctl (devfd, I_FLUSH, FLUSHR);
|
|
ioctl (devfd, I_POP, NULL);
|
|
}
|
|
if(dologmodem)
|
|
if (ioctl (devfd, I_PUSH, "strlog") != 0) {
|
|
syslog (LOG_ERR,"strlog %m");
|
|
exit (1);
|
|
}
|
|
if(!noslip) {
|
|
if (ioctl (devfd, I_PUSH, "slip") != 0) {
|
|
if(0)syslog (LOG_ERR,"slip: %m");
|
|
}
|
|
}
|
|
}
|
|
if(dolog) {
|
|
doqinfo++; dolog--;
|
|
}
|
|
if(dolog) {
|
|
docount++; dolog--;
|
|
}
|
|
if (dolog) {
|
|
--dolog;
|
|
if (ioctl (devfd, I_PUSH, "strlog") != 0) {
|
|
syslog (LOG_ERR,"strlog: %m");
|
|
exit (1);
|
|
}
|
|
}
|
|
if (dofakeh) {
|
|
if (ioctl (devfd, I_PUSH, "fakeh") != 0) {
|
|
syslog (LOG_ERR,"fakeh: %m");
|
|
exit (1);
|
|
}
|
|
}
|
|
if (dovanj) {
|
|
if (ioctl (devfd, I_PUSH, "van_j") < 0) {
|
|
#ifdef SIOCSIFENCAP
|
|
int i = SL_MODE_CSLIP|SL_OPT_ADAPTIVE;
|
|
ioctl(devfd,SIOCSIFENCAP,&i);
|
|
#endif
|
|
#ifdef SC_COMPRESS
|
|
ifflags |= SC_COMPRESS;
|
|
#endif
|
|
}
|
|
}
|
|
if (dolog) {
|
|
--dolog;
|
|
if (ioctl (devfd, I_PUSH, "strlog") != 0) {
|
|
syslog (LOG_ERR,"strlog: %m");
|
|
exit (1);
|
|
}
|
|
}
|
|
if (domon)
|
|
if (ioctl (devfd, I_PUSH, "ip_mon") != 0) {
|
|
syslog (LOG_ERR,"ip_mon: %m");
|
|
exit (1);
|
|
}
|
|
if (dolog) {
|
|
--dolog;
|
|
if (ioctl (devfd, I_PUSH, "strlog") != 0) {
|
|
syslog (LOG_ERR,"strlog: %m");
|
|
exit (1);
|
|
}
|
|
}
|
|
if (docount)
|
|
if (ioctl (devfd, I_PUSH, "count") != 0) {
|
|
syslog (LOG_ERR,"count: %m");
|
|
exit (1);
|
|
}
|
|
if(doqinfo)
|
|
if (ioctl (devfd, I_PUSH, "qinfo") != 0) {
|
|
syslog (LOG_ERR,"qinfo: %m");
|
|
exit (1);
|
|
}
|
|
if(dev != NULL) {
|
|
if (ioctl (devfd, I_PUSH, "str_if") != 0) {
|
|
int oerrno = errno;
|
|
int disc = N_SLIP;
|
|
|
|
if(ioctl(devfd,TIOCSETD,&disc) < 0) {
|
|
syslog (LOG_ERR,"str_if: %m");
|
|
errno = oerrno;
|
|
syslog (LOG_ERR,"str_if: %m");
|
|
exit (1);
|
|
}
|
|
}
|
|
if (ioctl (devfd, I_PUSH, "strlog") != 0) {
|
|
syslog (LOG_ERR,"strlog: %m");
|
|
}
|
|
if (ioctl (devfd, I_PUSH, "pr_on") != 0) {
|
|
syslog (LOG_ERR,"pr_on: %m");
|
|
}
|
|
if (0) {
|
|
if (ioctl (devfd, I_PUSH, "strlog") != 0) {
|
|
syslog (LOG_ERR,"strlog: %m");
|
|
exit (1);
|
|
}
|
|
}
|
|
}
|
|
if(dev != NULL || doenable)
|
|
enable ();
|
|
|
|
#ifdef HAVE_SETPGRP_2
|
|
setpgrp (0, pid);
|
|
#endif
|
|
#ifdef HAVE_SETPGRP_0
|
|
setpgrp();
|
|
#endif
|
|
#ifdef TIOCSPGRP
|
|
(void) ioctl (0, TIOCSPGRP, &pid);
|
|
#endif
|
|
|
|
alarm(0);
|
|
for (;;) {
|
|
char c;
|
|
int i = read (devfd, &c, 1);
|
|
int oerrno;
|
|
|
|
switch (i) {
|
|
case -1:
|
|
oerrno = errno;
|
|
syslog (LOG_DEBUG, "Driver: %m");
|
|
if (oerrno != EAGAIN && oerrno != EINTR) {
|
|
if(oerrno == EIO) pause();
|
|
goto Out;
|
|
}
|
|
break;
|
|
case 0:
|
|
goto Out;
|
|
default:
|
|
syslog (LOG_DEBUG, "Got Data %02x from driver -- down?", c);
|
|
(void) ioctl(devfd,I_FLUSH,FLUSHR);
|
|
}
|
|
}
|
|
/* At this point, we have decided to shut down */
|
|
Out:
|
|
syslog (LOG_DEBUG, "Terminating");
|
|
disable();
|
|
exit(1);
|
|
}
|