home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / mskermit.tar.gz / mskermit.tar / msnpkt.c < prev    next >
C/C++ Source or Header  |  1998-05-28  |  7KB  |  243 lines

  1. /* File MSNPKT.C
  2.  * Packet Driver interface
  3.  *
  4.  *    Copyright (C) 1982, 1997, Trustees of Columbia University in the 
  5.  *    City of New York.  The MS-DOS Kermit software may not be, in whole 
  6.  *    or in part, licensed or sold for profit as a software product itself,
  7.  *    nor may it be included in or distributed with commercial products
  8.  *    or otherwise distributed by commercial concerns to their clients 
  9.  *    or customers without written permission of the Office of Kermit 
  10.  *    Development and Distribution, Columbia University.  This copyright 
  11.  *    notice must not be removed, altered, or obscured.
  12.  *
  13.  * Written for MS-DOS Kermit by Joe R. Doupnik, 
  14.  *  Utah State University, jrd@cc.usu.edu, jrd@usu.Bitnet
  15.  *
  16.  * Last edit
  17.  * 12 Jan 1995 v3.14
  18.  */
  19. #include "msntcp.h"
  20. #include "msnlib.h"
  21.  
  22. #define BUFSIZE    6000             /* size of pkt receive buffer */
  23.  
  24. word    pkt_ip_type = 0x0008;        /* these are little endian values */
  25. word    pkt_arp_type = 0x0608;
  26. word    pkt_rarp_type = 0x3580;
  27.  
  28. int    pkt_ip_handle = -1;        /* -1 means invalid handle */
  29. int    pkt_arp_handle = -1;
  30. int    pkt_rarp_handle = -1;
  31.  
  32. int    pdversion, pdtype, pdnum, pdfunct;
  33. extern    word pktdevclass;
  34. extern    int pdinit(void *, void *);
  35. extern    int pdinfo(int *, int *, int *, int *, int *);
  36. extern    int pdaccess(int *, int, int *);
  37. extern    int pdclose(int);
  38. extern    eth_address eth_addr;            /* six byte array */
  39. extern    word MAC_len;
  40. extern    word mss;
  41. extern    byte kdebug;
  42.  
  43. byte pktbuf[BUFSIZE] = {0};    /* linked list packet receive buffer */
  44. static byte * pktbuf_read = pktbuf;
  45. byte pktwnum = 0;        /* seq number for packets written to buffer */
  46. byte pktrnum = 0;        /* seq number for packets read from buffer */
  47. byte * pktbuf_wrote = &pktbuf[BUFSIZE - 4];
  48. long watch_timeout;
  49.  
  50. int
  51. eth_init()
  52. {
  53.         pkt_buf_wipe();        /* clean out and init receiver buffer */
  54.     mss = ETH_MSS;        /* set default max seg size */
  55.     if (pdinit(pktbuf, eth_addr) == 0)
  56.             {
  57.         outs("\r\nCannot attach to an Ethernet Packet Driver");
  58.         outs(" or a Novell ODI driver.");
  59.         return( 0 );
  60.         }
  61.     pkt_buf_wipe();
  62.  
  63.                     /* lets find out about the driver */
  64.     if ((pdinfo(&pdversion, &pktdevclass, &pdtype, &pdnum, &pdfunct))
  65.         == 0)
  66.         {
  67.         outs("\r\nCannot obtain Packet Driver or ODI information");
  68.         return (0);
  69.         }
  70.  
  71.     if (pdaccess(&pkt_ip_type, 
  72.     (pktdevclass == PD_SLIP)? 0: sizeof(pkt_ip_handle), &pkt_ip_handle)
  73.         == 0)
  74.          {
  75.         outs("\r\n\7Cannot access IP type packets");
  76.         return (0);
  77.         }
  78.  
  79. /* Check for real SLIP and for ODI with SLIP_PPP; neither uses ARP and RARP */
  80. /* ODI returns length of MAC header, such as 6 for real Ethernet and 0
  81.    for SLIP and PPP. We get Ethernet style frames for ODI material. */
  82.     if (pktdevclass == PD_SLIP ||
  83.         ( pktdevclass == PD_ETHER && MAC_len == 0))
  84.         return (1);
  85.  
  86.     if (pdaccess(&pkt_arp_type, sizeof(pkt_arp_handle), &pkt_arp_handle)
  87.         == 0)
  88.          {
  89.         outs("\r\n\7Cannot access ARP type packets");
  90.         return (0);
  91.         }
  92.     return (1);                /* say success */
  93. }
  94.  
  95. int
  96. pkt_rarp_init()                /* access PD or ODI for RARP */
  97. {
  98.     if (pkt_rarp_handle != -1)
  99.         return (1);        /* have handle already */
  100.  
  101.     if (pdaccess(&pkt_rarp_type, sizeof(pkt_rarp_handle), &pkt_rarp_handle)
  102.         == 0)
  103.          {
  104.         outs("\r\n\7Cannot access RARP type packets");
  105.         return (0);
  106.         }
  107.     return (1);                /* say success */
  108. }
  109.  
  110. int
  111. pkt_release()
  112. {
  113.     register int status = 1;            /* assume success */
  114.  
  115.     if (pkt_ip_handle != -1)
  116.         if (pdclose(pkt_ip_handle) == 0)
  117.             {
  118.             outs("\r\nERROR releasing Packet Driver for IP");
  119.             status = 0;
  120.             }
  121.         else pkt_ip_handle = -1;    /* handle is out of service */
  122.  
  123.         if (pkt_arp_handle != -1)
  124.         if (pdclose(pkt_arp_handle) == 0)
  125.             {
  126.             outs("\r\nERROR releasing Packet Driver for ARP");
  127.             status = 0;
  128.             }
  129.         else pkt_arp_handle = -1;    /* handle is out of service */
  130.  
  131.     if (pkt_rarp_handle != -1)
  132.         if (pdclose(pkt_rarp_handle) == 0)
  133.             {
  134.             outs("\r\nERROR releasing Packet Driver for RARP");
  135.             status = 0;
  136.             }
  137.         else pkt_rarp_handle = -1;    /* handle is out of service */
  138.     return (status);
  139. }
  140.  
  141. /* Deliver pointer to start of packet (destination address) or NULL.
  142.  * Simple linked list: byte flag, byte pkt seq number, int count, 
  143.  * byte data[count] and so on.
  144.  * Status on the link flag byte is
  145.  * 0 = end of buffer (count has size to point to start of buffer)
  146.  * 1 = this slot is free (unused)
  147.  * 2 = this slot has an unread packet
  148.  * 4 = this slot is allocated for a packet, packet not yet loaded into it
  149.  * 8 = this slot has a packet which has been read once
  150.  * A two byte count value follows the flag byte, for number of bytes in 
  151.  * this slot. Pktbuf_read remembers the pointer to the last-read slot.
  152. */
  153.  
  154. void * 
  155. pkt_received()
  156. {
  157.     register byte * p;
  158.     register int i;
  159.  
  160.     p = pktbuf_read;            /* start with last read */
  161.     for (i = 0; i < 2 * (BUFSIZE / (60 + 4)); i++)    /* 2 * max pkts */
  162.         {
  163.         if (*(p+1) == pktrnum)
  164.         {
  165.         if (*p == 2)             /* 2 == ready to be read */
  166.             {            /* if this is the next pkt */
  167.              pktbuf_read = p;    /* where we have read */
  168.             *p = 8;            /* mark as have read */
  169.             pktrnum++;        /* next one to read */
  170.             watch_timeout = 0;    /* kill watchdog timer */
  171.             return (p + 4);        /* return ptr to pkt*/
  172.             }
  173.         if (*p == 4)             /* 4 == only allocated */
  174.             if (watch_timeout == 0)    /* if not started timing */
  175.                 {
  176.                 watch_timeout = set_timeout(1); /* 1 sec */
  177.                 return (NULL);
  178.                 }
  179.             else
  180.                 {    /* if timed out waiting for filling */
  181.                 if (chk_timeout(watch_timeout) == TIMED_OUT)
  182.                     {
  183.                     pkt_buf_wipe();    /* emergency treatment */
  184.                     if (kdebug)
  185.                 outs("\7 Flushing stuck receive queue\r\n");
  186.                     }
  187.                 return (NULL);
  188.                 }
  189.         }    /* end of *(p+1) == pktrnum and *p == 2 | 4 */
  190.  
  191. /* if link is:      end of buf  free      ready      allocated  have read */
  192.         if (*p == 0 || *p == 1 || *p == 2 || *p == 4 || *p == 8)
  193.             {
  194.             p += 4 + *(word *)(p+2);   /* point at next link */
  195.             continue;
  196.             }
  197.         else                /* bad link information */
  198.             {
  199.             pkt_buf_wipe();        /* emergency treatment */
  200.             if (kdebug) 
  201.                 outs("\7 Flushing corrupt receive queue\r\n");
  202.             break;
  203.             }
  204.         if (p == pktbuf_read)    break;    /* where we came in */
  205.         }
  206.     return (NULL);
  207. }
  208.     
  209. void
  210. pkt_buf_release(byte *p)    /* return a buffer to the pool */
  211. {
  212.     if (pktdevclass == PD_SLIP)
  213.         p -= 4;            /* just link info */
  214.     else
  215.         p -= 4 + 6 + 6 + 2;    /* link info and MAC header */
  216.  
  217.     if (*p == 8)            /* if packet has been read */
  218.         {
  219.         *(p+1) = pktrnum - 1;    /* backdate to avoid confusion */
  220.         *p = 1;            /* mark link as freed */
  221.         }
  222. }
  223.  
  224. void
  225. pkt_buf_wipe()                    /* clear all buffers */
  226. {
  227.     disable();
  228.     pktbuf[0] = 1;                /* flag first link as free */
  229.     pktbuf[1] = 0;
  230.     *(word *)&pktbuf[2] = BUFSIZE - 8; /* free space, size - two links */
  231.  
  232.     pktbuf[BUFSIZE - 4] = 0;        /* flag as end of buffer */
  233.     pktbuf[BUFSIZE - 3] = 0;        /* pkt buffer seq number */
  234.                 /* count below points to start of buffer */
  235.     *(int *)&pktbuf[BUFSIZE - 2] = - BUFSIZE; 
  236.     pktbuf_read = pktbuf;                /* where last read */
  237.     pktbuf_wrote = &pktbuf[BUFSIZE - 4];        /* where last wrote*/
  238.     pktwnum = pktrnum = 0;        /* reset buffer sequence numbers */
  239.     watch_timeout = 0;
  240.     enable();
  241. }
  242.  
  243.