home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / mscwattc / src / pcpkt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-15  |  6.3 KB  |  246 lines

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