home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / misc / tcpipsrc / asy.c < prev    next >
C/C++ Source or Header  |  1991-01-27  |  7KB  |  262 lines

  1. /* Generic serial line interface routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "config.h"
  7. #include "iface.h"
  8. #include "pktdrvr.h"
  9. #include "netuser.h"
  10. #include "asy.h"
  11. #include "8250.h"
  12. #include "ax25.h"
  13. #include "kiss.h"
  14. #include "ppp.h"
  15. #include "slip.h"
  16. #include "nrs.h"
  17. #include "config.h"
  18. #include "proc.h"
  19. #include "commands.h"
  20. #include "slcompress.h"
  21.  
  22. /* Attach a serial interface to the system
  23.  * argv[0]: hardware type, must be "asy"
  24.  * argv[1]: I/O address, e.g., "0x3f8"
  25.  * argv[2]: vector, e.g., "4"
  26.  * argv[3]: mode, may be:
  27.  *        "slip" (point-to-point SLIP)
  28.  *        "ax25" (AX.25 frame format in SLIP for raw TNC)
  29.  *        "nrs" (NET/ROM format serial protocol)
  30.  *        "ppp" (Point-to-Point Protocol, RFC1171, RFC1172)
  31.  * argv[4]: interface label, e.g., "sl0"
  32.  * argv[5]: receiver ring buffer size in bytes
  33.  * argv[6]: maximum transmission unit, bytes
  34.  * argv[7]: interface speed, e.g, "9600"
  35.  * argv[8]: optional flags, e.g., 'c' for cts flow control;
  36.  *          'v' for Van Jacobson TCP header compression (SLIP only,
  37.  *          use 'ppp ipcomp' command for VJ compression with PPP);
  38.  *        'r' for RLSD (RS232 pin 8, CD) physical link up/down
  39.  *        indicator (PPP only); 'a' for autobaud message handling
  40.  *        (PPP only)
  41.  */
  42. int
  43. asy_attach(argc,argv,p)
  44. int argc;
  45. char *argv[];
  46. void *p;
  47. {
  48.     register struct iface *if_asy;
  49.     int dev;
  50.     int mode;
  51.     int xdev;
  52.     int trigchar = -1;
  53.     char cts;
  54.     struct asy *asyp;
  55.     char rlsd = 0;
  56.     unsigned long autospeed = 0L;
  57. #if    defined(SLIP) || defined(AX25) || defined(PPP)
  58.     struct slip *sp;
  59. #endif
  60. #ifdef    NRS
  61.     struct nrs *np;
  62. #endif
  63.  
  64.     /* Find unused asy control block */
  65.     for(dev=0;dev < ASY_MAX;dev++){
  66.         asyp = &Asy[dev];
  67.         if(asyp->iface == NULLIF)
  68.             break;
  69.     }
  70.     if(dev >= ASY_MAX){
  71.         tprintf("Too many asynch controllers\n");
  72.         return -1;
  73.     }
  74.     if(if_lookup(argv[4]) != NULLIF){
  75.         tprintf("Interface %s already exists\n",argv[4]);
  76.         return -1;
  77.     }
  78.     if(strcmp(argv[3],"slip") == 0)
  79.         mode = SLIP_MODE;
  80.     else if(strcmp(argv[3],"ax25") == 0)
  81.         mode = AX25_MODE;
  82.     else if(strcmp(argv[3],"nrs") == 0)
  83.         mode = NRS_MODE;
  84.     else if(strcmp(argv[3],"ppp") == 0)
  85.         mode = PPP_MODE;
  86.     else 
  87.         mode = UNKNOWN_MODE;
  88.  
  89.     /* Create interface structure and fill in details */
  90.     if_asy = (struct iface *)callocw(1,sizeof(struct iface));
  91.     if_asy->addr = Ip_addr;
  92.     if_asy->name = strdup(argv[4]);
  93.     if_asy->mtu = atoi(argv[6]);
  94.     if_asy->dev = dev;
  95.     if_asy->stop = asy_stop;
  96.  
  97.     switch(mode){
  98. #ifdef    SLIP
  99.     case SLIP_MODE:
  100.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  101.             sp = &Slip[xdev];
  102.             if(sp->iface == NULLIF)
  103.                 break;
  104.         }
  105.         if(xdev >= SLIP_MAX) {
  106.             tprintf("Too many slip devices\n");
  107.             return -1;
  108.         }
  109.         setencap(if_asy,"SLIP");
  110.         if_asy->ioctl = asy_ioctl;
  111.         if_asy->raw = slip_raw;
  112.         if_asy->flags = 0;
  113.         if_asy->xdev = xdev;
  114.  
  115.         sp->iface = if_asy;
  116.         sp->send = asy_send;
  117.         sp->get = get_asy;
  118.         sp->type = CL_SERIAL_LINE;
  119.         trigchar = FR_END;
  120. #ifdef VJCOMPRESS
  121.         if((argc > 8) && (strchr(argv[8],'v') != NULLCHAR)) {
  122.             sp->escaped |= SLIP_VJCOMPR;
  123.             sp->slcomp = (struct slcompress *)mallocw(sizeof(struct slcompress));
  124.             sl_compress_init(sp->slcomp);
  125.         }
  126. #else
  127.         sp->slcomp = 0L;
  128. #endif    /* VJCOMPRESS */
  129.         if_asy->rxproc = newproc("asy rx",256,asy_rx,xdev,NULL,NULL,0);
  130.         break;
  131. #endif
  132. #ifdef    AX25
  133.     case AX25_MODE:  /* Set up a SLIP link to use AX.25 */
  134.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  135.             sp = &Slip[xdev];
  136.             if(sp->iface == NULLIF)
  137.                 break;
  138.         }
  139.         if(xdev >= SLIP_MAX) {
  140.             tprintf("Too many slip devices\n");
  141.             return -1;
  142.         }
  143.         setencap(if_asy,"AX25");
  144.         if_asy->ioctl = kiss_ioctl;
  145.         if_asy->raw = kiss_raw;
  146.         if(if_asy->hwaddr == NULLCHAR)
  147.             if_asy->hwaddr = mallocw(AXALEN);
  148.         memcpy(if_asy->hwaddr,Mycall,AXALEN);
  149.         if_asy->xdev = xdev;
  150.  
  151.         sp->iface = if_asy;
  152.         sp->send = asy_send;
  153.         sp->get = get_asy;
  154.         sp->type = CL_KISS;
  155.         trigchar = FR_END;
  156.         if_asy->rxproc = newproc("asy rx",256,asy_rx,xdev,NULL,NULL,0);
  157.         break;
  158. #endif
  159. #ifdef    NRS
  160.     case NRS_MODE: /* Set up a net/rom serial iface */
  161.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  162.             np = &Nrs[xdev];
  163.             if(np->iface == NULLIF)
  164.                 break;
  165.         }
  166.         if(xdev >= SLIP_MAX) {
  167.             tprintf("Too many nrs devices\n");
  168.             return -1;
  169.         }
  170.         /* no call supplied? */
  171.         setencap(if_asy,"AX25");
  172.         if_asy->ioctl = asy_ioctl;
  173.         if_asy->raw = nrs_raw;
  174.         if_asy->hwaddr = mallocw(AXALEN);
  175.         memcpy(if_asy->hwaddr,Mycall,AXALEN);
  176.         if_asy->xdev = xdev;
  177.         np->iface = if_asy;
  178.         np->send = asy_send;
  179.         np->get = get_asy;
  180.         trigchar = ETX;
  181.         if_asy->rxproc = newproc("nrs rx",256,nrs_recv,xdev,NULL,NULL,0);
  182.         break;
  183. #endif
  184. #ifdef    PPP
  185.     case PPP_MODE:    /* Setup for Point-to-Point Protocol */
  186.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  187.             sp = &Slip[xdev];
  188.             if(sp->iface == NULLIF)
  189.                 break;
  190.         }
  191.         if(xdev >= SLIP_MAX) {
  192.             tprintf("Too many slip/ppp devices\n");
  193.             return -1;
  194.         }
  195.         setencap(if_asy,"PPP");
  196.         if_asy->ioctl = asy_ioctl;
  197.         if_asy->raw = ppp_raw;
  198.         if_asy->flags = 0;
  199.         if_asy->xdev = xdev;
  200.  
  201.         sp->iface = if_asy;
  202.         sp->send = asy_send;
  203.         sp->get = get_asy;
  204.         sp->type = CL_PPP;
  205.         sp->get_rlsd = get_rlsd_asy;
  206.         sp->escaped = 0;
  207.         trigchar = HDLC_FLAG;
  208.         /* Allocate PPP control structure */
  209.         sp->pppio = (struct pppctl *)calloc(1,sizeof(struct pppctl));
  210.         if (sp->pppio == NULLPPPCTL) {
  211.             tprintf("Cannot allocate PPP control block\n");
  212.             free(if_asy->name);
  213.             free((char *)if_asy);
  214.             return -1;
  215.         }
  216.         /* Initialize parameters for various PPP phases/protocols */
  217.         if((argc > 8) && (strchr(argv[8],'r') != NULLCHAR))
  218.             rlsd = 1;
  219.         else
  220.             rlsd = 0;
  221.         if((argc > 8) && (strchr(argv[8],'a') != NULLCHAR)) {
  222.             autospeed = atoi(argv[7]);
  223.         } else {
  224.             autospeed = 0;
  225.         }
  226.         /* Initialize parameters for various PPP phases/protocols */
  227.         if (ppp_init(xdev,rlsd,autospeed) == -1) {
  228.             free(if_asy->name);
  229.             free((char *)if_asy);
  230.             return -1;
  231.         }
  232.         if (autospeed != 0) {
  233.             if_asy->rxproc = newproc("ppp autobaud", 256,
  234.              ppp_autobaud, xdev, NULL, NULL,0);
  235.         } else {
  236.             if_asy->rxproc = newproc("ppp recv", 256,
  237.              ppp_recv, xdev, NULL, NULL,0);
  238.         }
  239.         if (rlsd)
  240.             if_asy->txproc = newproc("ppp rlsd", 256, ppp_rlsd,
  241.              xdev, (void *)autospeed, NULL,0);
  242.         break;
  243. #endif /* PPP */
  244.     default:
  245.         tprintf("Mode %s unknown for interface %s\n",
  246.             argv[3],argv[4]);
  247.         free(if_asy->name);
  248.         free((char *)if_asy);
  249.         return -1;
  250.     }
  251.     if_asy->txproc = newproc("asy tx",256,asy_tx,dev,NULL,NULL,0);
  252.     if_asy->next = Ifaces;
  253.     Ifaces = if_asy;
  254.     if((argc > 8) && (strchr(argv[8],'c') != NULLCHAR))
  255.         cts = 1;
  256.     else
  257.         cts = 0;
  258.     asy_init(dev,if_asy,argv[1],argv[2],(unsigned)atoi(argv[5]),trigchar,cts,rlsd);
  259.     asy_speed(dev,atol(argv[7]),autospeed);
  260.     return 0;
  261. }
  262.