home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / hamradio / wattcp.zip / PCPKT.C < prev    next >
C/C++ Source or Header  |  1991-11-18  |  6KB  |  244 lines

  1. #include <copyright.h>
  2. #include <wattcp.h>
  3. #include <elib.h>
  4. #include <dos.h>
  5.  
  6.  
  7. #define MAXBUFS     5    /* maximum number of Ethernet buffers */
  8. #define BUFSIZE     1500
  9.  
  10.  
  11. #define INT_FIRST 0x60
  12. #define INT_LAST  0x80
  13. #define PKT_LINE "PKT DRVR"
  14. #define PD_DRIVER_INFO    0x1ff
  15. #define PD_ACCESS     0x200
  16. #define PD_RELEASE    0x300
  17. #define PD_SEND        0x400
  18. #define PD_GET_ADDRESS    0x600
  19. #define  CARRY         1         /* carry bit in flags register */
  20.  
  21. word _pktipofs = 0;            /* offset from header to start of pkt */
  22. word pkt_interrupt;
  23. word pkt_ip_type = 0x0008;        /* these are intelled values */
  24. word pkt_arp_type = 0x608;
  25.  
  26. byte pktbuf[MAXBUFS][ BUFSIZE + 2 ];    /* first byte is busy flag, 2nd spare */
  27. word  pkt_ip_handle;
  28. word  pkt_arp_handle;
  29. byte eth_addr[ 6 ] ;
  30. longword far *interrupts = 0L;
  31.  
  32.  
  33.  
  34. extern void _pktentry();
  35. extern void _pktasminit( void far *, int, int );
  36. extern int qcmp( void far *, void far *, int );
  37.  
  38.  
  39. pkt_init()
  40. {
  41.     struct REGPACK regs, regs2;
  42.     char far *temp;
  43.     int pd_type;    /* packet driver type */
  44.     int class;
  45.  
  46.     _pktasminit( pktbuf, MAXBUFS, BUFSIZE);
  47.     for (pkt_interrupt = INT_FIRST; pkt_interrupt <= INT_LAST; ++pkt_interrupt ) {
  48.     temp = getvect( pkt_interrupt );
  49.     temp = (char far *)(interrupts[ pkt_interrupt ]);
  50.     if ( !qcmp( &(temp[3]), PKT_LINE, sizeof( PKT_LINE ))) {
  51.         break;
  52.     }
  53.     }
  54.     if ( pkt_interrupt > INT_LAST ) {
  55.     outs("NO PACKET DRIVER FOUND");
  56.     return( 1 );
  57.     }
  58.  
  59.     /* lets find out about the driver */
  60.     regs.r_ax = PD_DRIVER_INFO;
  61.     intr( pkt_interrupt, ®s );
  62.  
  63.     /* handle old versions, assume a class and just keep trying */
  64.     if (regs.r_flags & CARRY ) {
  65.     for ( class = 0; class < 2; ++class ) {
  66.         _pktdevclass = (class) ? PD_SLIP : PD_ETHER;
  67.  
  68.         for (pd_type = 1; pd_type < 128; ++pd_type ) {
  69.         regs.r_ax = PD_ACCESS | _pktdevclass;  /* ETH, SLIP */
  70.         regs.r_bx = pd_type;        /* type */
  71.         regs.r_dx = 0;            /* if number */
  72.         regs.r_cx = sizeof( pkt_ip_type );
  73.         regs.r_ds = FP_SEG( &pkt_ip_type );
  74.         regs.r_si = FP_OFF( &pkt_ip_type );
  75.         regs.r_es = FP_SEG( _pktentry);
  76.         regs.r_di = FP_OFF( _pktentry);
  77.         intr( pkt_interrupt, ®s );
  78.         if ( ! (regs.r_flags & CARRY) ) break;
  79.         }
  80.  
  81.         if (pd_type == 128 ) {
  82.         outs("ERROR initializing packet driver\n\r");
  83.         return( 1 );
  84.         }
  85.         /* we have found a working type, so kill it */
  86.         regs.r_bx = regs.r_ax;    /* handle */
  87.         regs.r_ax = PD_RELEASE;
  88.         intr( pkt_interrupt, ®s );
  89.     }
  90.     } else {
  91.     pd_type = regs.r_dx;
  92.     switch ( _pktdevclass = (regs.r_cx >> 8)) {
  93.         case PD_ETHER : _pktipofs = 14;
  94.  
  95.         case PD_SLIP  : break;
  96.         default       : outs("ERROR: only ethernet packet drivers allowed\n\r");
  97.                 return( 1 );
  98.     }
  99.     }
  100.     regs.r_ax = PD_ACCESS | _pktdevclass;
  101.     regs.r_bx = 0xffff;  /* any type - was pd_type  type */
  102.     regs.r_dx = 0;            /* if number */
  103.     regs.r_cx = sizeof( pkt_ip_type );
  104.     regs.r_ds = FP_SEG( &pkt_ip_type );
  105.     regs.r_si = FP_OFF( &pkt_ip_type );
  106.     regs.r_es = FP_SEG( _pktentry);
  107.     regs.r_di = FP_OFF( _pktentry);
  108.     memcpy( ®s2, ®s, sizeof( regs ));
  109.     regs2.r_si = FP_OFF( &pkt_arp_type );
  110.     regs2.r_ds = FP_SEG( &pkt_arp_type );
  111.  
  112.     intr( pkt_interrupt, ®s );
  113.     if ( regs.r_flags & CARRY ) {
  114.     outs("ERROR # 0x");
  115.     outhex( regs.r_dx >> 8 );
  116.     outs(" accessing packet driver\n\r" );
  117.     return( 1 );
  118.     }
  119.     pkt_ip_handle = regs.r_ax;
  120.  
  121.     if (_pktdevclass != PD_SLIP) {
  122.     intr( pkt_interrupt, ®s2 );
  123.     if ( regs2.r_flags & CARRY ) {
  124.         regs.r_ax = PD_RELEASE;
  125.         regs.r_bx = pkt_ip_handle;
  126.         intr( pkt_interrupt, ®s );
  127.  
  128.         outs("ERROR # 0x");
  129.         outhex( regs2.r_dx >> 8 );
  130.         outs(" accessing packet driver\n\r" );
  131.         return( 1 );
  132.     }
  133.     pkt_arp_handle = regs2.r_ax;
  134.     }
  135.  
  136.     /* get ethernet address */
  137.     regs.r_ax = PD_GET_ADDRESS;
  138.     regs.r_bx = pkt_ip_handle;
  139.     regs.r_es = FP_SEG( eth_addr );
  140.     regs.r_di = FP_OFF( eth_addr );
  141.     regs.r_cx = sizeof( eth_addr );
  142.     intr( pkt_interrupt, ®s );
  143.     if ( regs.r_flags & CARRY ) {
  144.     outs("ERROR # reading ethernet address\n\r" );
  145.     return( 1 );
  146.     }
  147.  
  148.     return( 0 );
  149. }
  150. pkt_release()
  151. {
  152.     struct REGPACK regs;
  153.     int error;
  154.  
  155.     error = 0;
  156.  
  157.     if ( _pktdevclass != PD_SLIP ) {
  158.     regs.r_ax = PD_RELEASE;
  159.     regs.r_bx = pkt_arp_handle;
  160.     intr( pkt_interrupt, ®s );
  161.     if (regs.r_flags & CARRY ) {
  162.         outs("ERROR releasing packet driver for ARP\n\r");
  163.         error = 1;
  164.     }
  165.     }
  166.  
  167.     regs.r_ax = PD_RELEASE;
  168.     regs.r_bx = pkt_ip_handle;
  169.     intr( pkt_interrupt, ®s );
  170.     if (regs.r_flags & CARRY ) {
  171.     outs("ERROR releasing packet driver for IP\n\r");
  172.     error = 1;
  173.     }
  174.  
  175.     return( error );
  176. }
  177.  
  178. int pkt_send( char *buffer, int length )
  179. {
  180.     struct REGPACK regs;
  181.     int retries;
  182.  
  183.     retries = 5;
  184.     while (retries--) {
  185.         regs.r_ax = PD_SEND;
  186.         regs.r_ds = FP_SEG( buffer );
  187.         regs.r_si = FP_OFF( buffer );
  188.         regs.r_cx = length;
  189.         intr( pkt_interrupt, ®s );
  190.         if ( regs.r_flags & CARRY )
  191.             continue;
  192.         return( 0 );
  193.     }
  194.     return( 1 );
  195. }
  196.  
  197. /* return a buffer to the pool */
  198. pkt_buf_wipe()
  199. {
  200.     memset( pktbuf, 0, sizeof( byte ) * MAXBUFS * (BUFSIZE+ 2));
  201. }
  202. pkt_buf_release( char *ptr )
  203. {
  204.     *(ptr - (2 + 14)) = 0;
  205. }
  206. void * pkt_received()
  207. {
  208.     word i, old;
  209.     word oldin, newin;    /* ip sequence numbers */
  210.  
  211.     /* check if there are any */
  212.     old = oldin = 0xffff;
  213.  
  214.     for ( i = 0 ; i < MAXBUFS; ++i ) {
  215.     if ( *pktbuf[i] != 1 ) continue;
  216.  
  217.     newin = *(word*)(&pktbuf[i][ _pktipofs + 4 + 2]);
  218.     if ( newin <= oldin ) {
  219.         oldin = newin;
  220.         old = i;
  221.     }
  222.     }
  223.  
  224.     return( (old == -1) ? NULL : &pktbuf[old][2] );
  225. #ifdef OLD
  226.     for (i=0; i < MAXBUFS; ++i) {
  227.     if ( *pktbuf[i] == 1 ) {
  228.         *pktbuf[i] = 2;
  229.         return( &pktbuf[i][2] );
  230.     }
  231.     }
  232.     return( 0 );
  233. #endif OLD
  234. }
  235.  
  236. void * _pkt_eth_init()
  237. {
  238.     if ( pkt_init() ) {
  239.     outs("Program halted");
  240.     exit( 1 );
  241.     }
  242.     return( eth_addr );
  243. }
  244.