home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / SUN / SLIP / CSN_SLIP.TAR / slip-tip / slip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-05  |  5.6 KB  |  249 lines

  1. #ifndef lint
  2. static char *sccsid = "%W%    MS/ACF    %E%";
  3. #endif
  4. /*
  5.  *  tip/slip.c
  6.  *
  7.  *  This file contains the SLIP specific startup code.  It is designed
  8.  *  with both BSD sockets and Sun Streams in mind, though the socket
  9.  *  version has not been tested lately (but it SHOULD work).  
  10.  *
  11.  *  The code to set the route (basically an internal shell script) may
  12.  *  need tweeking on other systems, though it works on any of the
  13.  *  systems I have run into.
  14.  *
  15.  *  The alarm/DCD code is a HACK to detect loss of the line in the
  16.  *  absense of proper modems status signaling (broken in SunOS when
  17.  *  using the dialout device, serial line minor devices 128-255).
  18.  *  This has been reported, but I suspect that a fix will have to
  19.  *  wait for SunOS 4.2 or maybe 4.1.?.
  20.  *
  21.  *  Doug Kingston <dpk@morgan.com>
  22.  *  880219
  23.  */
  24.  
  25. #include "tip.h"
  26.  
  27. #include <sys/socket.h>
  28. #ifdef STREAMS
  29. #include <sys/stropts.h>
  30. #include <sys/sockio.h>
  31. #include <sys/termios.h>    /* has defines that clash with ioctl.h */
  32. #include <sys/slip.h>
  33. #endif STREAMS
  34. #include <netinet/in.h>
  35. #include <net/if.h>
  36.  
  37. #include <arpa/inet.h>
  38.  
  39. #define    DCD_SETTLING_TIME 1    /* time between DCD change and status check */
  40. #define    DCD_CHECK_INTERVAL 15    /* if > 0, time between automatic DCD checks */
  41.  
  42. int gotsig = 0;
  43. sigfunc_t dcd_handler();
  44.  
  45. runslip()
  46. {
  47.     int unit, s;
  48.     struct ifreq ifr;
  49. #ifdef STREAMS /* Using streams */
  50.     struct termios tios;
  51.  
  52.     /* pop all streams modules */
  53.     while (ioctl(FD, I_POP, 0) == 0)
  54.         continue;
  55.  
  56.     /* set up the line parameters */
  57.     if (ioctl(FD, TCGETS, (caddr_t)&tios) < 0) {
  58.         perror("ioctl (TCGETS)");
  59.         return(1);
  60.     }
  61.     tios.c_cflag = (tios.c_cflag&(CBAUD|CIBAUD))|CS8|CREAD|HUPCL;
  62.     tios.c_iflag = IGNBRK;
  63.     if (ioctl(FD, TCSETS, (caddr_t)&tios) < 0) {
  64.         perror("ioctl (TCSETS)");
  65.         return(1);
  66.     }
  67.  
  68.     /* push the SLIP module */
  69. #ifdef SUNOS40
  70.     if (ioctl(FD, I_PUSH, "slip") < 0) {
  71.         perror("ioctl (I_PUSH)");
  72.         return(1);
  73.     }
  74. #endif
  75. #ifdef SUNOS41
  76.         if (ioctl(FD, I_PUSH, "slipen") < 0) {
  77.         perror("ioctl (I_PUSH) slipen");
  78.         return(1);
  79.     }
  80.     if (ioctl(FD, I_PUSH, "str_ip") < 0) {
  81.         perror("ioctl (I_PUSH) str_ip");
  82.         return(1);
  83.     }
  84. #endif
  85.     /* find out what unit number we were assigned */
  86.     if (ioctl(FD, SLIOGUNIT, (caddr_t)&unit) < 0) {
  87.         perror("ioctl (SLIOGUNIT)");
  88.         return(1);
  89.     }
  90. #else /* not streams */
  91.     int ldisc = SLIPDISC;
  92.     if (ioctl(FD, TIOCSETD, &ldisc) < 0) {
  93.         perror("slipd: TIOCSETD");
  94.         return(1);
  95.     }
  96.     if (ioctl(FD, TIOCGETD, &unit) < 0) {    /* Hack to get slip number */
  97.         perror("slipd: TIOCGETD");
  98.         return(1);
  99.     }
  100. #endif STREAMS
  101.  
  102.     /* set the local and remote interface addresses */
  103.     s = socket(AF_INET, SOCK_DGRAM, 0);
  104.  
  105.     (void) sprintf(ifr.ifr_name, "slip%d", unit);
  106.     if (in_getaddr(SM, &ifr.ifr_addr) != 0) {
  107.         if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0) {
  108.             perror("ioctl (SIOCSIFADDR)");
  109.             return(1);
  110.         }
  111.     }
  112.  
  113.     (void) sprintf(ifr.ifr_name, "slip%d", unit);
  114.     if (in_getaddr(DA, &ifr.ifr_addr) != 0 ||
  115.         ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0) {
  116.         perror("ioctl (SIOCSIFDSTADDR)");
  117.         return(1);
  118.     }
  119.  
  120.     /* this has the side-effect of marking the interface up */
  121.     (void) sprintf(ifr.ifr_name, "slip%d", unit);
  122.     if (in_getaddr(SA, &ifr.ifr_addr) != 0 ||
  123.         ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) {
  124.         perror("ioctl (SIOCSIFADDR)");
  125.         return(1);
  126.     }
  127.  
  128.  
  129.     /* Set up default route if desired and not already present */
  130.     if (boolean(value(SETROUTE))) {
  131.         char buf[256];
  132.         char *argv[4];
  133.         char *envp[2];
  134.         int status;
  135.  
  136.         sprintf(buf, "if eval 'netstat -r|grep -s \"^default\"';\
  137.                   then echo default route already installed;\
  138.                   else route add 0 %s 3; fi", SA);
  139.         argv[0] = "/bin/sh";
  140.         argv[1] = "-c";
  141.         argv[2] = buf;
  142.         argv[3] = (char *)0;
  143.  
  144.         envp[0] = "PATH=/bin:/usr/bin:/usr/ucb:/etc:/usr/etc";
  145.         envp[1] = (char *)0;
  146.  
  147.         switch (fork()) {
  148.         case 0:        /* Child */
  149.             execve(argv[0], argv, envp);
  150.             exit(1);
  151.         case -1:
  152.             perror("tip: route add: fork");
  153.             break;
  154.         default:    /* Parent */
  155.             wait(&status);
  156.         }
  157.     }
  158.  
  159.     fprintf(stderr, "\07[SLIP running]\r\n");
  160.  
  161.     /* set up signal handlers */
  162.     (void) sigblock(sigmask(SIGALRM));
  163.     (void) signal(SIGALRM, dcd_handler);
  164. #if defined(SIGDCD) && SIGDCD > 0
  165.     (void) signal(SIGDCD, dcd_handler);
  166. #endif
  167.  
  168.     /* twiddle thumbs until we get a signal */
  169.     while (1) {
  170.         alarm(DCD_CHECK_INTERVAL);
  171.         sigpause(0);
  172. #if defined(SIGDCD) && SIGDCD > 0
  173.         (void) sigblock(sigmask(SIGALRM)|sigmask(SIGDCD));
  174. #else
  175.         (void) sigblock(sigmask(SIGALRM));
  176. #endif SIGDCD
  177.         if (gotsig && lowdcd(FD)) {
  178.             sleep(DCD_SETTLING_TIME);
  179.             if (lowdcd(FD))
  180.                 break;
  181.         }
  182.         gotsig = 0;
  183.     }
  184.     return(0);
  185. }
  186.  
  187. abort_slip()
  188. {
  189. #ifdef STREAMS
  190.     /* pop the SLIP stream module */
  191.     while(ioctl(FD, I_POP, 0) == 0);
  192. #else
  193.     int ldisc = 0;
  194.     (void)ioctl(FD, TIOCSETD, &ldisc);
  195. #endif
  196. }
  197.  
  198. sigfunc_t
  199. dcd_handler()
  200. {
  201.     gotsig = 1;
  202. }
  203.  
  204. /* Use TIOCMGET to test if DCD is low on the port of the passed descriptor */
  205. int
  206. lowdcd(fd)
  207.     int fd;
  208. {
  209.     int mbits;
  210.  
  211.     if (ioctl(fd, TIOCMGET, (caddr_t)&mbits) < 0)
  212.         return 1;    /* port is dead, we die */
  213.     return !(mbits & TIOCM_CAR);
  214. }
  215.  
  216. in_getaddr(s, saddr)
  217.     char *s;
  218.     struct sockaddr *saddr;
  219. {
  220.     register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
  221.     struct hostent *hp;
  222.     struct netent *np;
  223.     unsigned long val;
  224.     extern unsigned long inet_addr();
  225.  
  226.     bzero((caddr_t)saddr, sizeof(struct sockaddr));
  227.     sin->sin_family = AF_INET;
  228.     val = inet_addr(s);
  229.     if (val != ((unsigned long) -1)) {
  230.         sin->sin_addr.s_addr = val;
  231.         return(0);
  232.     }
  233.     hp = gethostbyname(s);
  234.     if (hp) {
  235.         sin->sin_family = hp->h_addrtype;
  236.         bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
  237.         return(0);
  238.     }
  239.     np = getnetbyname(s);
  240.     if (np) {
  241.         sin->sin_family = np->n_addrtype;
  242.         sin->sin_addr = inet_makeaddr((int)np->n_net, (int)INADDR_ANY);
  243.         return(0);
  244.     }
  245.     (void) fprintf(stderr, "tip: %s: bad value\n", s);
  246.     exit(1);
  247.     /* NOTREACHED */
  248. }
  249.